1/* 2 * I2C initialization for PNX4008. 3 * 4 * Author: Vitaly Wool <vitalywool@gmail.com> 5 * 6 * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under 7 * the terms of the GNU General Public License version 2. This program 8 * is licensed "as is" without any warranty of any kind, whether express 9 * or implied. 10 */ 11 12#include <linux/clk.h> 13#include <linux/i2c.h> 14#include <linux/i2c-pnx.h> 15#include <linux/platform_device.h> 16#include <linux/err.h> 17#include <asm/arch/platform.h> 18#include <asm/arch/i2c.h> 19 20static int set_clock_run(struct platform_device *pdev) 21{ 22 struct clk *clk; 23 char name[10]; 24 int retval = 0; 25 26 snprintf(name, 10, "i2c%d_ck", pdev->id); 27 clk = clk_get(&pdev->dev, name); 28 if (!IS_ERR(clk)) { 29 clk_set_rate(clk, 1); 30 clk_put(clk); 31 } else 32 retval = -ENOENT; 33 34 return retval; 35} 36 37static int set_clock_stop(struct platform_device *pdev) 38{ 39 struct clk *clk; 40 char name[10]; 41 int retval = 0; 42 43 snprintf(name, 10, "i2c%d_ck", pdev->id); 44 clk = clk_get(&pdev->dev, name); 45 if (!IS_ERR(clk)) { 46 clk_set_rate(clk, 0); 47 clk_put(clk); 48 } else 49 retval = -ENOENT; 50 51 return retval; 52} 53 54static int i2c_pnx_suspend(struct platform_device *pdev, pm_message_t state) 55{ 56 int retval = 0; 57#ifdef CONFIG_PM 58 retval = set_clock_run(pdev); 59#endif 60 return retval; 61} 62 63static int i2c_pnx_resume(struct platform_device *pdev) 64{ 65 int retval = 0; 66#ifdef CONFIG_PM 67 retval = set_clock_run(pdev); 68#endif 69 return retval; 70} 71 72static u32 calculate_input_freq(struct platform_device *pdev) 73{ 74 return HCLK_MHZ; 75} 76 77 78static struct i2c_pnx_algo_data pnx_algo_data0 = { 79 .base = PNX4008_I2C1_BASE, 80 .irq = I2C_1_INT, 81}; 82 83static struct i2c_pnx_algo_data pnx_algo_data1 = { 84 .base = PNX4008_I2C2_BASE, 85 .irq = I2C_2_INT, 86}; 87 88static struct i2c_pnx_algo_data pnx_algo_data2 = { 89 .base = (PNX4008_USB_CONFIG_BASE + 0x300), 90 .irq = USB_I2C_INT, 91}; 92 93static struct i2c_adapter pnx_adapter0 = { 94 .name = I2C_CHIP_NAME "0", 95 .algo_data = &pnx_algo_data0, 96}; 97static struct i2c_adapter pnx_adapter1 = { 98 .name = I2C_CHIP_NAME "1", 99 .algo_data = &pnx_algo_data1, 100}; 101 102static struct i2c_adapter pnx_adapter2 = { 103 .name = "USB-I2C", 104 .algo_data = &pnx_algo_data2, 105}; 106 107static struct i2c_pnx_data i2c0_data = { 108 .suspend = i2c_pnx_suspend, 109 .resume = i2c_pnx_resume, 110 .calculate_input_freq = calculate_input_freq, 111 .set_clock_run = set_clock_run, 112 .set_clock_stop = set_clock_stop, 113 .adapter = &pnx_adapter0, 114}; 115 116static struct i2c_pnx_data i2c1_data = { 117 .suspend = i2c_pnx_suspend, 118 .resume = i2c_pnx_resume, 119 .calculate_input_freq = calculate_input_freq, 120 .set_clock_run = set_clock_run, 121 .set_clock_stop = set_clock_stop, 122 .adapter = &pnx_adapter1, 123}; 124 125static struct i2c_pnx_data i2c2_data = { 126 .suspend = i2c_pnx_suspend, 127 .resume = i2c_pnx_resume, 128 .calculate_input_freq = calculate_input_freq, 129 .set_clock_run = set_clock_run, 130 .set_clock_stop = set_clock_stop, 131 .adapter = &pnx_adapter2, 132}; 133 134static struct platform_device i2c0_device = { 135 .name = "pnx-i2c", 136 .id = 0, 137 .dev = { 138 .platform_data = &i2c0_data, 139 }, 140}; 141 142static struct platform_device i2c1_device = { 143 .name = "pnx-i2c", 144 .id = 1, 145 .dev = { 146 .platform_data = &i2c1_data, 147 }, 148}; 149 150static struct platform_device i2c2_device = { 151 .name = "pnx-i2c", 152 .id = 2, 153 .dev = { 154 .platform_data = &i2c2_data, 155 }, 156}; 157 158static struct platform_device *devices[] __initdata = { 159 &i2c0_device, 160 &i2c1_device, 161 &i2c2_device, 162}; 163 164void __init pnx4008_register_i2c_devices(void) 165{ 166 platform_add_devices(devices, ARRAY_SIZE(devices)); 167} 168