0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <linux/io.h>
0020 #include <linux/i2c.h>
0021 #include <linux/slab.h>
0022 #include <linux/delay.h>
0023 #include <linux/errno.h>
0024 #include <linux/kernel.h>
0025 #include <linux/module.h>
0026 #include <linux/gpio/consumer.h>
0027 #include <linux/interrupt.h>
0028 #include <linux/platform_device.h>
0029
0030
0031
0032
0033
0034 #define CBUS_ADDR_BITS 3
0035 #define CBUS_REG_BITS 5
0036
0037 struct cbus_host {
0038 spinlock_t lock;
0039 struct device *dev;
0040 struct gpio_desc *clk;
0041 struct gpio_desc *dat;
0042 struct gpio_desc *sel;
0043 };
0044
0045
0046
0047
0048
0049
0050 static void cbus_send_bit(struct cbus_host *host, unsigned bit)
0051 {
0052 gpiod_set_value(host->dat, bit ? 1 : 0);
0053 gpiod_set_value(host->clk, 1);
0054 gpiod_set_value(host->clk, 0);
0055 }
0056
0057
0058
0059
0060
0061
0062
0063 static void cbus_send_data(struct cbus_host *host, unsigned data, unsigned len)
0064 {
0065 int i;
0066
0067 for (i = len; i > 0; i--)
0068 cbus_send_bit(host, data & (1 << (i - 1)));
0069 }
0070
0071
0072
0073
0074
0075 static int cbus_receive_bit(struct cbus_host *host)
0076 {
0077 int ret;
0078
0079 gpiod_set_value(host->clk, 1);
0080 ret = gpiod_get_value(host->dat);
0081 gpiod_set_value(host->clk, 0);
0082 return ret;
0083 }
0084
0085
0086
0087
0088
0089 static int cbus_receive_word(struct cbus_host *host)
0090 {
0091 int ret = 0;
0092 int i;
0093
0094 for (i = 16; i > 0; i--) {
0095 int bit = cbus_receive_bit(host);
0096
0097 if (bit < 0)
0098 return bit;
0099
0100 if (bit)
0101 ret |= 1 << (i - 1);
0102 }
0103 return ret;
0104 }
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114 static int cbus_transfer(struct cbus_host *host, char rw, unsigned dev,
0115 unsigned reg, unsigned data)
0116 {
0117 unsigned long flags;
0118 int ret;
0119
0120
0121 spin_lock_irqsave(&host->lock, flags);
0122
0123
0124 gpiod_set_value(host->sel, 0);
0125
0126
0127 gpiod_direction_output(host->dat, 1);
0128
0129
0130 cbus_send_data(host, dev, CBUS_ADDR_BITS);
0131
0132
0133 cbus_send_bit(host, rw == I2C_SMBUS_READ);
0134
0135
0136 cbus_send_data(host, reg, CBUS_REG_BITS);
0137
0138 if (rw == I2C_SMBUS_WRITE) {
0139 cbus_send_data(host, data, 16);
0140 ret = 0;
0141 } else {
0142 ret = gpiod_direction_input(host->dat);
0143 if (ret) {
0144 dev_dbg(host->dev, "failed setting direction\n");
0145 goto out;
0146 }
0147 gpiod_set_value(host->clk, 1);
0148
0149 ret = cbus_receive_word(host);
0150 if (ret < 0) {
0151 dev_dbg(host->dev, "failed receiving data\n");
0152 goto out;
0153 }
0154 }
0155
0156
0157 gpiod_set_value(host->sel, 1);
0158 gpiod_set_value(host->clk, 1);
0159 gpiod_set_value(host->clk, 0);
0160
0161 out:
0162 spin_unlock_irqrestore(&host->lock, flags);
0163
0164 return ret;
0165 }
0166
0167 static int cbus_i2c_smbus_xfer(struct i2c_adapter *adapter,
0168 u16 addr,
0169 unsigned short flags,
0170 char read_write,
0171 u8 command,
0172 int size,
0173 union i2c_smbus_data *data)
0174 {
0175 struct cbus_host *chost = i2c_get_adapdata(adapter);
0176 int ret;
0177
0178 if (size != I2C_SMBUS_WORD_DATA)
0179 return -EINVAL;
0180
0181 ret = cbus_transfer(chost, read_write == I2C_SMBUS_READ, addr,
0182 command, data->word);
0183 if (ret < 0)
0184 return ret;
0185
0186 if (read_write == I2C_SMBUS_READ)
0187 data->word = ret;
0188
0189 return 0;
0190 }
0191
0192 static u32 cbus_i2c_func(struct i2c_adapter *adapter)
0193 {
0194 return I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA;
0195 }
0196
0197 static const struct i2c_algorithm cbus_i2c_algo = {
0198 .smbus_xfer = cbus_i2c_smbus_xfer,
0199 .smbus_xfer_atomic = cbus_i2c_smbus_xfer,
0200 .functionality = cbus_i2c_func,
0201 };
0202
0203 static int cbus_i2c_remove(struct platform_device *pdev)
0204 {
0205 struct i2c_adapter *adapter = platform_get_drvdata(pdev);
0206
0207 i2c_del_adapter(adapter);
0208
0209 return 0;
0210 }
0211
0212 static int cbus_i2c_probe(struct platform_device *pdev)
0213 {
0214 struct i2c_adapter *adapter;
0215 struct cbus_host *chost;
0216
0217 adapter = devm_kzalloc(&pdev->dev, sizeof(struct i2c_adapter),
0218 GFP_KERNEL);
0219 if (!adapter)
0220 return -ENOMEM;
0221
0222 chost = devm_kzalloc(&pdev->dev, sizeof(*chost), GFP_KERNEL);
0223 if (!chost)
0224 return -ENOMEM;
0225
0226 if (gpiod_count(&pdev->dev, NULL) != 3)
0227 return -ENODEV;
0228 chost->clk = devm_gpiod_get_index(&pdev->dev, NULL, 0, GPIOD_OUT_LOW);
0229 if (IS_ERR(chost->clk))
0230 return PTR_ERR(chost->clk);
0231 chost->dat = devm_gpiod_get_index(&pdev->dev, NULL, 1, GPIOD_IN);
0232 if (IS_ERR(chost->dat))
0233 return PTR_ERR(chost->dat);
0234 chost->sel = devm_gpiod_get_index(&pdev->dev, NULL, 2, GPIOD_OUT_HIGH);
0235 if (IS_ERR(chost->sel))
0236 return PTR_ERR(chost->sel);
0237 gpiod_set_consumer_name(chost->clk, "CBUS clk");
0238 gpiod_set_consumer_name(chost->dat, "CBUS dat");
0239 gpiod_set_consumer_name(chost->sel, "CBUS sel");
0240
0241 adapter->owner = THIS_MODULE;
0242 adapter->class = I2C_CLASS_HWMON;
0243 adapter->dev.parent = &pdev->dev;
0244 adapter->dev.of_node = pdev->dev.of_node;
0245 adapter->nr = pdev->id;
0246 adapter->timeout = HZ;
0247 adapter->algo = &cbus_i2c_algo;
0248 strscpy(adapter->name, "CBUS I2C adapter", sizeof(adapter->name));
0249
0250 spin_lock_init(&chost->lock);
0251 chost->dev = &pdev->dev;
0252
0253 i2c_set_adapdata(adapter, chost);
0254 platform_set_drvdata(pdev, adapter);
0255
0256 return i2c_add_numbered_adapter(adapter);
0257 }
0258
0259 #if defined(CONFIG_OF)
0260 static const struct of_device_id i2c_cbus_dt_ids[] = {
0261 { .compatible = "i2c-cbus-gpio", },
0262 { }
0263 };
0264 MODULE_DEVICE_TABLE(of, i2c_cbus_dt_ids);
0265 #endif
0266
0267 static struct platform_driver cbus_i2c_driver = {
0268 .probe = cbus_i2c_probe,
0269 .remove = cbus_i2c_remove,
0270 .driver = {
0271 .name = "i2c-cbus-gpio",
0272 .of_match_table = of_match_ptr(i2c_cbus_dt_ids),
0273 },
0274 };
0275 module_platform_driver(cbus_i2c_driver);
0276
0277 MODULE_ALIAS("platform:i2c-cbus-gpio");
0278 MODULE_DESCRIPTION("CBUS I2C driver");
0279 MODULE_AUTHOR("Juha Yrjölä");
0280 MODULE_AUTHOR("David Weinehall");
0281 MODULE_AUTHOR("Mikko Ylinen");
0282 MODULE_AUTHOR("Felipe Balbi");
0283 MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>");
0284 MODULE_LICENSE("GPL");