1 /* 2 * CBUS I2C driver for Nokia Internet Tablets. 3 * 4 * Copyright (C) 2004-2010 Nokia Corporation 5 * 6 * Based on code written by Juha Yrjölä, David Weinehall, Mikko Ylinen and 7 * Felipe Balbi. Converted to I2C driver by Aaro Koskinen. 8 * 9 * This file is subject to the terms and conditions of the GNU General 10 * Public License. See the file "COPYING" in the main directory of this 11 * archive for more details. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 */ 18 19 #include <linux/io.h> 20 #include <linux/i2c.h> 21 #include <linux/gpio.h> 22 #include <linux/init.h> 23 #include <linux/slab.h> 24 #include <linux/delay.h> 25 #include <linux/errno.h> 26 #include <linux/kernel.h> 27 #include <linux/module.h> 28 #include <linux/of_gpio.h> 29 #include <linux/interrupt.h> 30 #include <linux/platform_device.h> 31 #include <linux/platform_data/i2c-cbus-gpio.h> 32 33 /* 34 * Bit counts are derived from Nokia implementation. These should be checked 35 * if other CBUS implementations appear. 36 */ 37 #define CBUS_ADDR_BITS 3 38 #define CBUS_REG_BITS 5 39 40 struct cbus_host { 41 spinlock_t lock; /* host lock */ 42 struct device *dev; 43 int clk_gpio; 44 int dat_gpio; 45 int sel_gpio; 46 }; 47 48 /** 49 * cbus_send_bit - sends one bit over the bus 50 * @host: the host we're using 51 * @bit: one bit of information to send 52 */ 53 static void cbus_send_bit(struct cbus_host *host, unsigned bit) 54 { 55 gpio_set_value(host->dat_gpio, bit ? 1 : 0); 56 gpio_set_value(host->clk_gpio, 1); 57 gpio_set_value(host->clk_gpio, 0); 58 } 59 60 /** 61 * cbus_send_data - sends @len amount of data over the bus 62 * @host: the host we're using 63 * @data: the data to send 64 * @len: size of the transfer 65 */ 66 static void cbus_send_data(struct cbus_host *host, unsigned data, unsigned len) 67 { 68 int i; 69 70 for (i = len; i > 0; i--) 71 cbus_send_bit(host, data & (1 << (i - 1))); 72 } 73 74 /** 75 * cbus_receive_bit - receives one bit from the bus 76 * @host: the host we're using 77 */ 78 static int cbus_receive_bit(struct cbus_host *host) 79 { 80 int ret; 81 82 gpio_set_value(host->clk_gpio, 1); 83 ret = gpio_get_value(host->dat_gpio); 84 gpio_set_value(host->clk_gpio, 0); 85 return ret; 86 } 87 88 /** 89 * cbus_receive_word - receives 16-bit word from the bus 90 * @host: the host we're using 91 */ 92 static int cbus_receive_word(struct cbus_host *host) 93 { 94 int ret = 0; 95 int i; 96 97 for (i = 16; i > 0; i--) { 98 int bit = cbus_receive_bit(host); 99 100 if (bit < 0) 101 return bit; 102 103 if (bit) 104 ret |= 1 << (i - 1); 105 } 106 return ret; 107 } 108 109 /** 110 * cbus_transfer - transfers data over the bus 111 * @host: the host we're using 112 * @rw: read/write flag 113 * @dev: device address 114 * @reg: register address 115 * @data: if @rw == I2C_SBUS_WRITE data to send otherwise 0 116 */ 117 static int cbus_transfer(struct cbus_host *host, char rw, unsigned dev, 118 unsigned reg, unsigned data) 119 { 120 unsigned long flags; 121 int ret; 122 123 /* We don't want interrupts disturbing our transfer */ 124 spin_lock_irqsave(&host->lock, flags); 125 126 /* Reset state and start of transfer, SEL stays down during transfer */ 127 gpio_set_value(host->sel_gpio, 0); 128 129 /* Set the DAT pin to output */ 130 gpio_direction_output(host->dat_gpio, 1); 131 132 /* Send the device address */ 133 cbus_send_data(host, dev, CBUS_ADDR_BITS); 134 135 /* Send the rw flag */ 136 cbus_send_bit(host, rw == I2C_SMBUS_READ); 137 138 /* Send the register address */ 139 cbus_send_data(host, reg, CBUS_REG_BITS); 140 141 if (rw == I2C_SMBUS_WRITE) { 142 cbus_send_data(host, data, 16); 143 ret = 0; 144 } else { 145 ret = gpio_direction_input(host->dat_gpio); 146 if (ret) { 147 dev_dbg(host->dev, "failed setting direction\n"); 148 goto out; 149 } 150 gpio_set_value(host->clk_gpio, 1); 151 152 ret = cbus_receive_word(host); 153 if (ret < 0) { 154 dev_dbg(host->dev, "failed receiving data\n"); 155 goto out; 156 } 157 } 158 159 /* Indicate end of transfer, SEL goes up until next transfer */ 160 gpio_set_value(host->sel_gpio, 1); 161 gpio_set_value(host->clk_gpio, 1); 162 gpio_set_value(host->clk_gpio, 0); 163 164 out: 165 spin_unlock_irqrestore(&host->lock, flags); 166 167 return ret; 168 } 169 170 static int cbus_i2c_smbus_xfer(struct i2c_adapter *adapter, 171 u16 addr, 172 unsigned short flags, 173 char read_write, 174 u8 command, 175 int size, 176 union i2c_smbus_data *data) 177 { 178 struct cbus_host *chost = i2c_get_adapdata(adapter); 179 int ret; 180 181 if (size != I2C_SMBUS_WORD_DATA) 182 return -EINVAL; 183 184 ret = cbus_transfer(chost, read_write == I2C_SMBUS_READ, addr, 185 command, data->word); 186 if (ret < 0) 187 return ret; 188 189 if (read_write == I2C_SMBUS_READ) 190 data->word = ret; 191 192 return 0; 193 } 194 195 static u32 cbus_i2c_func(struct i2c_adapter *adapter) 196 { 197 return I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA; 198 } 199 200 static const struct i2c_algorithm cbus_i2c_algo = { 201 .smbus_xfer = cbus_i2c_smbus_xfer, 202 .functionality = cbus_i2c_func, 203 }; 204 205 static int cbus_i2c_remove(struct platform_device *pdev) 206 { 207 struct i2c_adapter *adapter = platform_get_drvdata(pdev); 208 209 return i2c_del_adapter(adapter); 210 } 211 212 static int cbus_i2c_probe(struct platform_device *pdev) 213 { 214 struct i2c_adapter *adapter; 215 struct cbus_host *chost; 216 int ret; 217 218 adapter = devm_kzalloc(&pdev->dev, sizeof(struct i2c_adapter), 219 GFP_KERNEL); 220 if (!adapter) 221 return -ENOMEM; 222 223 chost = devm_kzalloc(&pdev->dev, sizeof(*chost), GFP_KERNEL); 224 if (!chost) 225 return -ENOMEM; 226 227 if (pdev->dev.of_node) { 228 struct device_node *dnode = pdev->dev.of_node; 229 if (of_gpio_count(dnode) != 3) 230 return -ENODEV; 231 chost->clk_gpio = of_get_gpio(dnode, 0); 232 chost->dat_gpio = of_get_gpio(dnode, 1); 233 chost->sel_gpio = of_get_gpio(dnode, 2); 234 } else if (pdev->dev.platform_data) { 235 struct i2c_cbus_platform_data *pdata = pdev->dev.platform_data; 236 chost->clk_gpio = pdata->clk_gpio; 237 chost->dat_gpio = pdata->dat_gpio; 238 chost->sel_gpio = pdata->sel_gpio; 239 } else { 240 return -ENODEV; 241 } 242 243 adapter->owner = THIS_MODULE; 244 adapter->class = I2C_CLASS_HWMON; 245 adapter->dev.parent = &pdev->dev; 246 adapter->nr = pdev->id; 247 adapter->timeout = HZ; 248 adapter->algo = &cbus_i2c_algo; 249 strlcpy(adapter->name, "CBUS I2C adapter", sizeof(adapter->name)); 250 251 spin_lock_init(&chost->lock); 252 chost->dev = &pdev->dev; 253 254 ret = devm_gpio_request_one(&pdev->dev, chost->clk_gpio, 255 GPIOF_OUT_INIT_LOW, "CBUS clk"); 256 if (ret) 257 return ret; 258 259 ret = devm_gpio_request_one(&pdev->dev, chost->dat_gpio, GPIOF_IN, 260 "CBUS data"); 261 if (ret) 262 return ret; 263 264 ret = devm_gpio_request_one(&pdev->dev, chost->sel_gpio, 265 GPIOF_OUT_INIT_HIGH, "CBUS sel"); 266 if (ret) 267 return ret; 268 269 i2c_set_adapdata(adapter, chost); 270 platform_set_drvdata(pdev, adapter); 271 272 return i2c_add_numbered_adapter(adapter); 273 } 274 275 #if defined(CONFIG_OF) 276 static const struct of_device_id i2c_cbus_dt_ids[] = { 277 { .compatible = "i2c-cbus-gpio", }, 278 { } 279 }; 280 MODULE_DEVICE_TABLE(of, i2c_cbus_dt_ids); 281 #endif 282 283 static struct platform_driver cbus_i2c_driver = { 284 .probe = cbus_i2c_probe, 285 .remove = cbus_i2c_remove, 286 .driver = { 287 .owner = THIS_MODULE, 288 .name = "i2c-cbus-gpio", 289 }, 290 }; 291 module_platform_driver(cbus_i2c_driver); 292 293 MODULE_ALIAS("platform:i2c-cbus-gpio"); 294 MODULE_DESCRIPTION("CBUS I2C driver"); 295 MODULE_AUTHOR("Juha Yrjölä"); 296 MODULE_AUTHOR("David Weinehall"); 297 MODULE_AUTHOR("Mikko Ylinen"); 298 MODULE_AUTHOR("Felipe Balbi"); 299 MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>"); 300 MODULE_LICENSE("GPL"); 301