aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via/via_i2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/via/via_i2c.c')
-rw-r--r--drivers/video/via/via_i2c.c74
1 files changed, 31 insertions, 43 deletions
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c
index b5253e3099f8..478829281562 100644
--- a/drivers/video/via/via_i2c.c
+++ b/drivers/video/via/via_i2c.c
@@ -21,13 +21,18 @@
21 21
22#include "global.h" 22#include "global.h"
23 23
24/*
25 * There can only be one set of these, so there's no point in having
26 * them be dynamically allocated...
27 */
28#define VIAFB_NUM_I2C 5
29static struct via_i2c_stuff via_i2c_par[VIAFB_NUM_I2C];
30
24static void via_i2c_setscl(void *data, int state) 31static void via_i2c_setscl(void *data, int state)
25{ 32{
26 u8 val; 33 u8 val;
27 struct via_i2c_adap_cfg *adap_data = data; 34 struct via_port_cfg *adap_data = data;
28 35
29 DEBUG_MSG(KERN_DEBUG "reading index 0x%02x from IO 0x%x\n",
30 adap_data->ioport_index, adap_data->io_port);
31 val = viafb_read_reg(adap_data->io_port, 36 val = viafb_read_reg(adap_data->io_port,
32 adap_data->ioport_index) & 0xF0; 37 adap_data->ioport_index) & 0xF0;
33 if (state) 38 if (state)
@@ -35,10 +40,10 @@ static void via_i2c_setscl(void *data, int state)
35 else 40 else
36 val &= ~0x20; 41 val &= ~0x20;
37 switch (adap_data->type) { 42 switch (adap_data->type) {
38 case VIA_I2C_I2C: 43 case VIA_PORT_I2C:
39 val |= 0x01; 44 val |= 0x01;
40 break; 45 break;
41 case VIA_I2C_GPIO: 46 case VIA_PORT_GPIO:
42 val |= 0x80; 47 val |= 0x80;
43 break; 48 break;
44 default: 49 default:
@@ -50,7 +55,7 @@ static void via_i2c_setscl(void *data, int state)
50 55
51static int via_i2c_getscl(void *data) 56static int via_i2c_getscl(void *data)
52{ 57{
53 struct via_i2c_adap_cfg *adap_data = data; 58 struct via_port_cfg *adap_data = data;
54 59
55 if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08) 60 if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08)
56 return 1; 61 return 1;
@@ -59,7 +64,7 @@ static int via_i2c_getscl(void *data)
59 64
60static int via_i2c_getsda(void *data) 65static int via_i2c_getsda(void *data)
61{ 66{
62 struct via_i2c_adap_cfg *adap_data = data; 67 struct via_port_cfg *adap_data = data;
63 68
64 if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04) 69 if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04)
65 return 1; 70 return 1;
@@ -69,7 +74,7 @@ static int via_i2c_getsda(void *data)
69static void via_i2c_setsda(void *data, int state) 74static void via_i2c_setsda(void *data, int state)
70{ 75{
71 u8 val; 76 u8 val;
72 struct via_i2c_adap_cfg *adap_data = data; 77 struct via_port_cfg *adap_data = data;
73 78
74 val = viafb_read_reg(adap_data->io_port, 79 val = viafb_read_reg(adap_data->io_port,
75 adap_data->ioport_index) & 0xF0; 80 adap_data->ioport_index) & 0xF0;
@@ -78,10 +83,10 @@ static void via_i2c_setsda(void *data, int state)
78 else 83 else
79 val &= ~0x10; 84 val &= ~0x10;
80 switch (adap_data->type) { 85 switch (adap_data->type) {
81 case VIA_I2C_I2C: 86 case VIA_PORT_I2C:
82 val |= 0x01; 87 val |= 0x01;
83 break; 88 break;
84 case VIA_I2C_GPIO: 89 case VIA_PORT_GPIO:
85 val |= 0x40; 90 val |= 0x40;
86 break; 91 break;
87 default: 92 default:
@@ -103,8 +108,7 @@ int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata)
103 mm1[0] = index; 108 mm1[0] = index;
104 msgs[0].len = 1; msgs[1].len = 1; 109 msgs[0].len = 1; msgs[1].len = 1;
105 msgs[0].buf = mm1; msgs[1].buf = pdata; 110 msgs[0].buf = mm1; msgs[1].buf = pdata;
106 return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter, 111 return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2);
107 msgs, 2);
108} 112}
109 113
110int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data) 114int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data)
@@ -116,8 +120,7 @@ int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data)
116 msgs.addr = slave_addr / 2; 120 msgs.addr = slave_addr / 2;
117 msgs.len = 2; 121 msgs.len = 2;
118 msgs.buf = msg; 122 msgs.buf = msg;
119 return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter, 123 return i2c_transfer(&via_i2c_par[adap].adapter, &msgs, 1);
120 &msgs, 1);
121} 124}
122 125
123int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len) 126int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len)
@@ -131,13 +134,12 @@ int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len
131 mm1[0] = index; 134 mm1[0] = index;
132 msgs[0].len = 1; msgs[1].len = buff_len; 135 msgs[0].len = 1; msgs[1].len = buff_len;
133 msgs[0].buf = mm1; msgs[1].buf = buff; 136 msgs[0].buf = mm1; msgs[1].buf = buff;
134 return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter, 137 return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2);
135 msgs, 2);
136} 138}
137 139
138static int create_i2c_bus(struct i2c_adapter *adapter, 140static int create_i2c_bus(struct i2c_adapter *adapter,
139 struct i2c_algo_bit_data *algo, 141 struct i2c_algo_bit_data *algo,
140 struct via_i2c_adap_cfg *adap_cfg, 142 struct via_port_cfg *adap_cfg,
141 struct pci_dev *pdev) 143 struct pci_dev *pdev)
142{ 144{
143 DEBUG_MSG(KERN_DEBUG "viafb: creating bus adap=0x%p, algo_bit_data=0x%p, adap_cfg=0x%p\n", adapter, algo, adap_cfg); 145 DEBUG_MSG(KERN_DEBUG "viafb: creating bus adap=0x%p, algo_bit_data=0x%p, adap_cfg=0x%p\n", adapter, algo, adap_cfg);
@@ -170,31 +172,15 @@ static int create_i2c_bus(struct i2c_adapter *adapter,
170 return i2c_bit_add_bus(adapter); 172 return i2c_bit_add_bus(adapter);
171} 173}
172 174
173/* 175int viafb_create_i2c_busses(struct via_port_cfg *configs)
174 * By default, we only activate busses on ports 2c and 31 to avoid
175 * conflicts with other possible users; that default can be changed
176 * below.
177 */
178static struct via_i2c_adap_cfg adap_configs[] = {
179 [VIA_I2C_ADAP_26] = { VIA_I2C_I2C, VIASR, 0x26, 0 },
180 [VIA_I2C_ADAP_31] = { VIA_I2C_I2C, VIASR, 0x31, 1 },
181 [VIA_I2C_ADAP_25] = { VIA_I2C_GPIO, VIASR, 0x25, 0 },
182 [VIA_I2C_ADAP_2C] = { VIA_I2C_GPIO, VIASR, 0x2c, 1 },
183 [VIA_I2C_ADAP_3D] = { VIA_I2C_GPIO, VIASR, 0x3d, 0 },
184 { 0, 0, 0, 0 }
185};
186
187int viafb_create_i2c_busses(struct viafb_par *viapar)
188{ 176{
189 int i, ret; 177 int i, ret;
190 178
191 for (i = 0; i < VIAFB_NUM_I2C; i++) { 179 for (i = 0; i < VIAFB_NUM_PORTS; i++) {
192 struct via_i2c_adap_cfg *adap_cfg = &adap_configs[i]; 180 struct via_port_cfg *adap_cfg = configs++;
193 struct via_i2c_stuff *i2c_stuff = &viapar->shared->i2c_stuff[i]; 181 struct via_i2c_stuff *i2c_stuff = &via_i2c_par[i];
194 182
195 if (adap_cfg->type == 0) 183 if (adap_cfg->type == 0 || adap_cfg->mode != VIA_MODE_I2C)
196 break;
197 if (!adap_cfg->is_active)
198 continue; 184 continue;
199 185
200 ret = create_i2c_bus(&i2c_stuff->adapter, 186 ret = create_i2c_bus(&i2c_stuff->adapter,
@@ -211,14 +197,16 @@ int viafb_create_i2c_busses(struct viafb_par *viapar)
211 return 0; 197 return 0;
212} 198}
213 199
214void viafb_delete_i2c_busses(struct viafb_par *par) 200void viafb_delete_i2c_busses(void)
215{ 201{
216 int i; 202 int i;
217 203
218 for (i = 0; i < ARRAY_SIZE(par->shared->i2c_stuff); i++) { 204 for (i = 0; i < VIAFB_NUM_PORTS; i++) {
219 struct via_i2c_stuff *i2c_stuff = &par->shared->i2c_stuff[i]; 205 struct via_i2c_stuff *i2c_stuff = &via_i2c_par[i];
220 /* only remove those entries in the array that we've 206 /*
221 * actually used (and thus initialized algo_data) */ 207 * Only remove those entries in the array that we've
208 * actually used (and thus initialized algo_data)
209 */
222 if (i2c_stuff->adapter.algo_data == &i2c_stuff->algo) 210 if (i2c_stuff->adapter.algo_data == &i2c_stuff->algo)
223 i2c_del_adapter(&i2c_stuff->adapter); 211 i2c_del_adapter(&i2c_stuff->adapter);
224 } 212 }