diff options
Diffstat (limited to 'drivers/video/via/via_i2c.c')
-rw-r--r-- | drivers/video/via/via_i2c.c | 74 |
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 | ||
29 | static struct via_i2c_stuff via_i2c_par[VIAFB_NUM_I2C]; | ||
30 | |||
24 | static void via_i2c_setscl(void *data, int state) | 31 | static 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 | ||
51 | static int via_i2c_getscl(void *data) | 56 | static 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 | ||
60 | static int via_i2c_getsda(void *data) | 65 | static 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) | |||
69 | static void via_i2c_setsda(void *data, int state) | 74 | static 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 | ||
110 | int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data) | 114 | int 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 | ||
123 | int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len) | 126 | int 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 | ||
138 | static int create_i2c_bus(struct i2c_adapter *adapter, | 140 | static 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 | /* | 175 | int 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 | */ | ||
178 | static 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 | |||
187 | int 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 | ||
214 | void viafb_delete_i2c_busses(struct viafb_par *par) | 200 | void 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 | } |