0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/platform_device.h>
0009 #include <linux/delay.h>
0010 #include <linux/spinlock.h>
0011 #include <linux/module.h>
0012 #include <linux/via-core.h>
0013 #include <linux/via_i2c.h>
0014
0015
0016
0017
0018
0019 #define VIAFB_NUM_I2C 5
0020 static struct via_i2c_stuff via_i2c_par[VIAFB_NUM_I2C];
0021 static struct viafb_dev *i2c_vdev;
0022
0023 static void via_i2c_setscl(void *data, int state)
0024 {
0025 u8 val;
0026 struct via_port_cfg *adap_data = data;
0027 unsigned long flags;
0028
0029 spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
0030 val = via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0xF0;
0031 if (state)
0032 val |= 0x20;
0033 else
0034 val &= ~0x20;
0035 switch (adap_data->type) {
0036 case VIA_PORT_I2C:
0037 val |= 0x01;
0038 break;
0039 case VIA_PORT_GPIO:
0040 val |= 0x82;
0041 break;
0042 default:
0043 printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n");
0044 }
0045 via_write_reg(adap_data->io_port, adap_data->ioport_index, val);
0046 spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
0047 }
0048
0049 static int via_i2c_getscl(void *data)
0050 {
0051 struct via_port_cfg *adap_data = data;
0052 unsigned long flags;
0053 int ret = 0;
0054
0055 spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
0056 if (adap_data->type == VIA_PORT_GPIO)
0057 via_write_reg_mask(adap_data->io_port, adap_data->ioport_index,
0058 0, 0x80);
0059 if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08)
0060 ret = 1;
0061 spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
0062 return ret;
0063 }
0064
0065 static int via_i2c_getsda(void *data)
0066 {
0067 struct via_port_cfg *adap_data = data;
0068 unsigned long flags;
0069 int ret = 0;
0070
0071 spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
0072 if (adap_data->type == VIA_PORT_GPIO)
0073 via_write_reg_mask(adap_data->io_port, adap_data->ioport_index,
0074 0, 0x40);
0075 if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04)
0076 ret = 1;
0077 spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
0078 return ret;
0079 }
0080
0081 static void via_i2c_setsda(void *data, int state)
0082 {
0083 u8 val;
0084 struct via_port_cfg *adap_data = data;
0085 unsigned long flags;
0086
0087 spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
0088 val = via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0xF0;
0089 if (state)
0090 val |= 0x10;
0091 else
0092 val &= ~0x10;
0093 switch (adap_data->type) {
0094 case VIA_PORT_I2C:
0095 val |= 0x01;
0096 break;
0097 case VIA_PORT_GPIO:
0098 val |= 0x42;
0099 break;
0100 default:
0101 printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n");
0102 }
0103 via_write_reg(adap_data->io_port, adap_data->ioport_index, val);
0104 spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
0105 }
0106
0107 int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata)
0108 {
0109 int ret;
0110 u8 mm1[] = {0x00};
0111 struct i2c_msg msgs[2];
0112
0113 if (!via_i2c_par[adap].is_active)
0114 return -ENODEV;
0115 *pdata = 0;
0116 msgs[0].flags = 0;
0117 msgs[1].flags = I2C_M_RD;
0118 msgs[0].addr = msgs[1].addr = slave_addr / 2;
0119 mm1[0] = index;
0120 msgs[0].len = 1; msgs[1].len = 1;
0121 msgs[0].buf = mm1; msgs[1].buf = pdata;
0122 ret = i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2);
0123 if (ret == 2)
0124 ret = 0;
0125 else if (ret >= 0)
0126 ret = -EIO;
0127
0128 return ret;
0129 }
0130
0131 int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data)
0132 {
0133 int ret;
0134 u8 msg[2] = { index, data };
0135 struct i2c_msg msgs;
0136
0137 if (!via_i2c_par[adap].is_active)
0138 return -ENODEV;
0139 msgs.flags = 0;
0140 msgs.addr = slave_addr / 2;
0141 msgs.len = 2;
0142 msgs.buf = msg;
0143 ret = i2c_transfer(&via_i2c_par[adap].adapter, &msgs, 1);
0144 if (ret == 1)
0145 ret = 0;
0146 else if (ret >= 0)
0147 ret = -EIO;
0148
0149 return ret;
0150 }
0151
0152 int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len)
0153 {
0154 int ret;
0155 u8 mm1[] = {0x00};
0156 struct i2c_msg msgs[2];
0157
0158 if (!via_i2c_par[adap].is_active)
0159 return -ENODEV;
0160 msgs[0].flags = 0;
0161 msgs[1].flags = I2C_M_RD;
0162 msgs[0].addr = msgs[1].addr = slave_addr / 2;
0163 mm1[0] = index;
0164 msgs[0].len = 1; msgs[1].len = buff_len;
0165 msgs[0].buf = mm1; msgs[1].buf = buff;
0166 ret = i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2);
0167 if (ret == 2)
0168 ret = 0;
0169 else if (ret >= 0)
0170 ret = -EIO;
0171
0172 return ret;
0173 }
0174
0175
0176
0177
0178
0179 struct i2c_adapter *viafb_find_i2c_adapter(enum viafb_i2c_adap which)
0180 {
0181 struct via_i2c_stuff *stuff = &via_i2c_par[which];
0182
0183 return &stuff->adapter;
0184 }
0185 EXPORT_SYMBOL_GPL(viafb_find_i2c_adapter);
0186
0187
0188 static int create_i2c_bus(struct i2c_adapter *adapter,
0189 struct i2c_algo_bit_data *algo,
0190 struct via_port_cfg *adap_cfg,
0191 struct pci_dev *pdev)
0192 {
0193 algo->setsda = via_i2c_setsda;
0194 algo->setscl = via_i2c_setscl;
0195 algo->getsda = via_i2c_getsda;
0196 algo->getscl = via_i2c_getscl;
0197 algo->udelay = 10;
0198 algo->timeout = 2;
0199 algo->data = adap_cfg;
0200
0201 sprintf(adapter->name, "viafb i2c io_port idx 0x%02x",
0202 adap_cfg->ioport_index);
0203 adapter->owner = THIS_MODULE;
0204 adapter->class = I2C_CLASS_DDC;
0205 adapter->algo_data = algo;
0206 if (pdev)
0207 adapter->dev.parent = &pdev->dev;
0208 else
0209 adapter->dev.parent = NULL;
0210
0211
0212
0213 via_i2c_setsda(adap_cfg, 1);
0214 via_i2c_setscl(adap_cfg, 1);
0215 udelay(20);
0216
0217 return i2c_bit_add_bus(adapter);
0218 }
0219
0220 static int viafb_i2c_probe(struct platform_device *platdev)
0221 {
0222 int i, ret;
0223 struct via_port_cfg *configs;
0224
0225 i2c_vdev = platdev->dev.platform_data;
0226 configs = i2c_vdev->port_cfg;
0227
0228 for (i = 0; i < VIAFB_NUM_PORTS; i++) {
0229 struct via_port_cfg *adap_cfg = configs++;
0230 struct via_i2c_stuff *i2c_stuff = &via_i2c_par[i];
0231
0232 i2c_stuff->is_active = 0;
0233 if (adap_cfg->type == 0 || adap_cfg->mode != VIA_MODE_I2C)
0234 continue;
0235 ret = create_i2c_bus(&i2c_stuff->adapter,
0236 &i2c_stuff->algo, adap_cfg,
0237 NULL);
0238 if (ret < 0) {
0239 printk(KERN_ERR "viafb: cannot create i2c bus %u:%d\n",
0240 i, ret);
0241 continue;
0242 }
0243 i2c_stuff->is_active = 1;
0244 }
0245
0246 return 0;
0247 }
0248
0249 static int viafb_i2c_remove(struct platform_device *platdev)
0250 {
0251 int i;
0252
0253 for (i = 0; i < VIAFB_NUM_PORTS; i++) {
0254 struct via_i2c_stuff *i2c_stuff = &via_i2c_par[i];
0255
0256
0257
0258
0259 if (i2c_stuff->is_active)
0260 i2c_del_adapter(&i2c_stuff->adapter);
0261 }
0262 return 0;
0263 }
0264
0265 static struct platform_driver via_i2c_driver = {
0266 .driver = {
0267 .name = "viafb-i2c",
0268 },
0269 .probe = viafb_i2c_probe,
0270 .remove = viafb_i2c_remove,
0271 };
0272
0273 int viafb_i2c_init(void)
0274 {
0275 return platform_driver_register(&via_i2c_driver);
0276 }
0277
0278 void viafb_i2c_exit(void)
0279 {
0280 platform_driver_unregister(&via_i2c_driver);
0281 }