diff options
author | Harald Welte <laforge@gnumonks.org> | 2009-05-22 12:35:39 -0400 |
---|---|---|
committer | Jonathan Corbet <corbet@lwn.net> | 2010-04-27 15:01:45 -0400 |
commit | 277d32a36cba0b42c9c6836ff07f9b978566e95c (patch) | |
tree | 7161c2ddeb6064a42ba4babe3678a0493ecf6365 /drivers/video | |
parent | c205d932530719d2a6ddb9152650e5bbe80c9400 (diff) |
viafb: rework the I2C support in the VIA framebuffer driver
This patch changes the way how the various I2C busses are used internally
inside the viafb driver: Previosuly, only a single i2c_adapter was created,
even though two different hardware I2C busses are accessed: A structure member
in a global variable was modified to indicate the bus to be used.
Now, all existing hardware busses are registered with the i2c core, and the
viafb_i2c_{read,write}byte[s]() function take the adapter number as function
call parameter, rather than referring to the global structure member.
[jc: even more painful merge with mainline changes ->2.6.34]
[jc: painful merge with OLPC changes]
Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Cc: ScottFang@viatech.com.cn
Cc: JosephChan@via.com.tw
Signed-off-by: Harald Welte <HaraldWelte@viatech.com>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/via/dvi.c | 35 | ||||
-rw-r--r-- | drivers/video/via/lcd.c | 19 | ||||
-rw-r--r-- | drivers/video/via/via_i2c.c | 171 | ||||
-rw-r--r-- | drivers/video/via/via_i2c.h | 43 | ||||
-rw-r--r-- | drivers/video/via/viafbdev.c | 6 | ||||
-rw-r--r-- | drivers/video/via/viafbdev.h | 4 | ||||
-rw-r--r-- | drivers/video/via/vt1636.c | 36 | ||||
-rw-r--r-- | drivers/video/via/vt1636.h | 2 |
8 files changed, 182 insertions, 134 deletions
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index abe59b8c7a05..be513701e4e6 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c | |||
@@ -96,7 +96,7 @@ int viafb_tmds_trasmitter_identify(void) | |||
96 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS; | 96 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS; |
97 | viaparinfo->chip_info-> | 97 | viaparinfo->chip_info-> |
98 | tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; | 98 | tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; |
99 | viaparinfo->chip_info->tmds_chip_info.i2c_port = I2CPORTINDEX; | 99 | viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_I2C_ADAP_31; |
100 | if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) { | 100 | if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) { |
101 | /* | 101 | /* |
102 | * Currently only support 12bits,dual edge,add 24bits mode later | 102 | * Currently only support 12bits,dual edge,add 24bits mode later |
@@ -110,7 +110,7 @@ int viafb_tmds_trasmitter_identify(void) | |||
110 | viaparinfo->chip_info->tmds_chip_info.i2c_port); | 110 | viaparinfo->chip_info->tmds_chip_info.i2c_port); |
111 | return OK; | 111 | return OK; |
112 | } else { | 112 | } else { |
113 | viaparinfo->chip_info->tmds_chip_info.i2c_port = GPIOPORTINDEX; | 113 | viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_I2C_ADAP_2C; |
114 | if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) | 114 | if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) |
115 | != FAIL) { | 115 | != FAIL) { |
116 | tmds_register_write(0x08, 0x3b); | 116 | tmds_register_write(0x08, 0x3b); |
@@ -160,32 +160,26 @@ int viafb_tmds_trasmitter_identify(void) | |||
160 | 160 | ||
161 | static void tmds_register_write(int index, u8 data) | 161 | static void tmds_register_write(int index, u8 data) |
162 | { | 162 | { |
163 | viaparinfo->shared->i2c_stuff.i2c_port = | 163 | viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.i2c_port, |
164 | viaparinfo->chip_info->tmds_chip_info.i2c_port; | 164 | viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, |
165 | 165 | index, data); | |
166 | viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info. | ||
167 | tmds_chip_slave_addr, index, | ||
168 | data); | ||
169 | } | 166 | } |
170 | 167 | ||
171 | static int tmds_register_read(int index) | 168 | static int tmds_register_read(int index) |
172 | { | 169 | { |
173 | u8 data; | 170 | u8 data; |
174 | 171 | ||
175 | viaparinfo->shared->i2c_stuff.i2c_port = | 172 | viafb_i2c_readbyte(viaparinfo->chip_info->tmds_chip_info.i2c_port, |
176 | viaparinfo->chip_info->tmds_chip_info.i2c_port; | 173 | (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, |
177 | viafb_i2c_readbyte((u8) viaparinfo->chip_info-> | 174 | (u8) index, &data); |
178 | tmds_chip_info.tmds_chip_slave_addr, | ||
179 | (u8) index, &data); | ||
180 | return data; | 175 | return data; |
181 | } | 176 | } |
182 | 177 | ||
183 | static int tmds_register_read_bytes(int index, u8 *buff, int buff_len) | 178 | static int tmds_register_read_bytes(int index, u8 *buff, int buff_len) |
184 | { | 179 | { |
185 | viaparinfo->shared->i2c_stuff.i2c_port = | 180 | viafb_i2c_readbytes(viaparinfo->chip_info->tmds_chip_info.i2c_port, |
186 | viaparinfo->chip_info->tmds_chip_info.i2c_port; | 181 | (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, |
187 | viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info. | 182 | (u8) index, buff, buff_len); |
188 | tmds_chip_slave_addr, (u8) index, buff, buff_len); | ||
189 | return 0; | 183 | return 0; |
190 | } | 184 | } |
191 | 185 | ||
@@ -541,9 +535,10 @@ void viafb_dvi_enable(void) | |||
541 | else | 535 | else |
542 | data = 0x37; | 536 | data = 0x37; |
543 | viafb_i2c_writebyte(viaparinfo->chip_info-> | 537 | viafb_i2c_writebyte(viaparinfo->chip_info-> |
544 | tmds_chip_info. | 538 | tmds_chip_info.i2c_port, |
545 | tmds_chip_slave_addr, | 539 | viaparinfo->chip_info-> |
546 | 0x08, data); | 540 | tmds_chip_info.tmds_chip_slave_addr, |
541 | 0x08, data); | ||
547 | } | 542 | } |
548 | } | 543 | } |
549 | } | 544 | } |
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index 09020f0b2d2a..e19441d9e49f 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c | |||
@@ -172,18 +172,16 @@ static bool lvds_identify_integratedlvds(void) | |||
172 | 172 | ||
173 | int viafb_lvds_trasmitter_identify(void) | 173 | int viafb_lvds_trasmitter_identify(void) |
174 | { | 174 | { |
175 | viaparinfo->shared->i2c_stuff.i2c_port = I2CPORTINDEX; | 175 | if (viafb_lvds_identify_vt1636(VIA_I2C_ADAP_31)) { |
176 | if (viafb_lvds_identify_vt1636()) { | 176 | viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_I2C_ADAP_31; |
177 | viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX; | ||
178 | DEBUG_MSG(KERN_INFO | 177 | DEBUG_MSG(KERN_INFO |
179 | "Found VIA VT1636 LVDS on port i2c 0x31 \n"); | 178 | "Found VIA VT1636 LVDS on port i2c 0x31\n"); |
180 | } else { | 179 | } else { |
181 | viaparinfo->shared->i2c_stuff.i2c_port = GPIOPORTINDEX; | 180 | if (viafb_lvds_identify_vt1636(VIA_I2C_ADAP_2C)) { |
182 | if (viafb_lvds_identify_vt1636()) { | ||
183 | viaparinfo->chip_info->lvds_chip_info.i2c_port = | 181 | viaparinfo->chip_info->lvds_chip_info.i2c_port = |
184 | GPIOPORTINDEX; | 182 | VIA_I2C_ADAP_2C; |
185 | DEBUG_MSG(KERN_INFO | 183 | DEBUG_MSG(KERN_INFO |
186 | "Found VIA VT1636 LVDS on port gpio 0x2c \n"); | 184 | "Found VIA VT1636 LVDS on port gpio 0x2c\n"); |
187 | } | 185 | } |
188 | } | 186 | } |
189 | 187 | ||
@@ -421,9 +419,8 @@ static int lvds_register_read(int index) | |||
421 | { | 419 | { |
422 | u8 data; | 420 | u8 data; |
423 | 421 | ||
424 | viaparinfo->shared->i2c_stuff.i2c_port = GPIOPORTINDEX; | 422 | viafb_i2c_readbyte(VIA_I2C_ADAP_2C, |
425 | viafb_i2c_readbyte((u8) viaparinfo->chip_info-> | 423 | (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr, |
426 | lvds_chip_info.lvds_chip_slave_addr, | ||
427 | (u8) index, &data); | 424 | (u8) index, &data); |
428 | return data; | 425 | return data; |
429 | } | 426 | } |
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c index 15543e968248..8f8e0bf0cf91 100644 --- a/drivers/video/via/via_i2c.c +++ b/drivers/video/via/via_i2c.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | 2 | * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved. |
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | 3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. |
4 | 4 | ||
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -24,40 +24,44 @@ | |||
24 | static void via_i2c_setscl(void *data, int state) | 24 | static void via_i2c_setscl(void *data, int state) |
25 | { | 25 | { |
26 | u8 val; | 26 | u8 val; |
27 | struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; | 27 | struct via_i2c_adap_cfg *adap_data = data; |
28 | 28 | ||
29 | val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0; | 29 | printk(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, | ||
32 | adap_data->ioport_index) & 0xF0; | ||
30 | if (state) | 33 | if (state) |
31 | val |= 0x20; | 34 | val |= 0x20; |
32 | else | 35 | else |
33 | val &= ~0x20; | 36 | val &= ~0x20; |
34 | switch (via_i2c_chan->i2c_port) { | 37 | switch (adap_data->type) { |
35 | case I2CPORTINDEX: | 38 | case VIA_I2C_I2C: |
36 | val |= 0x01; | 39 | val |= 0x01; |
37 | break; | 40 | break; |
38 | case GPIOPORTINDEX: | 41 | case VIA_I2C_GPIO: |
39 | val |= 0x80; | 42 | val |= 0x80; |
40 | break; | 43 | break; |
41 | default: | 44 | default: |
42 | DEBUG_MSG("via_i2c: specify wrong i2c port.\n"); | 45 | DEBUG_MSG("viafb_i2c: specify wrong i2c type.\n"); |
43 | } | 46 | } |
44 | viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val); | 47 | viafb_write_reg(adap_data->ioport_index, |
48 | adap_data->io_port, val); | ||
45 | } | 49 | } |
46 | 50 | ||
47 | static int via_i2c_getscl(void *data) | 51 | static int via_i2c_getscl(void *data) |
48 | { | 52 | { |
49 | struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; | 53 | struct via_i2c_adap_cfg *adap_data = data; |
50 | 54 | ||
51 | if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x08) | 55 | if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08) |
52 | return 1; | 56 | return 1; |
53 | return 0; | 57 | return 0; |
54 | } | 58 | } |
55 | 59 | ||
56 | static int via_i2c_getsda(void *data) | 60 | static int via_i2c_getsda(void *data) |
57 | { | 61 | { |
58 | struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; | 62 | struct via_i2c_adap_cfg *adap_data = data; |
59 | 63 | ||
60 | if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x04) | 64 | if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04) |
61 | return 1; | 65 | return 1; |
62 | return 0; | 66 | return 0; |
63 | } | 67 | } |
@@ -65,27 +69,29 @@ static int via_i2c_getsda(void *data) | |||
65 | static void via_i2c_setsda(void *data, int state) | 69 | static void via_i2c_setsda(void *data, int state) |
66 | { | 70 | { |
67 | u8 val; | 71 | u8 val; |
68 | struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; | 72 | struct via_i2c_adap_cfg *adap_data = data; |
69 | 73 | ||
70 | val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0; | 74 | val = viafb_read_reg(adap_data->io_port, |
75 | adap_data->ioport_index) & 0xF0; | ||
71 | if (state) | 76 | if (state) |
72 | val |= 0x10; | 77 | val |= 0x10; |
73 | else | 78 | else |
74 | val &= ~0x10; | 79 | val &= ~0x10; |
75 | switch (via_i2c_chan->i2c_port) { | 80 | switch (adap_data->type) { |
76 | case I2CPORTINDEX: | 81 | case VIA_I2C_I2C: |
77 | val |= 0x01; | 82 | val |= 0x01; |
78 | break; | 83 | break; |
79 | case GPIOPORTINDEX: | 84 | case VIA_I2C_GPIO: |
80 | val |= 0x40; | 85 | val |= 0x40; |
81 | break; | 86 | break; |
82 | default: | 87 | default: |
83 | DEBUG_MSG("via_i2c: specify wrong i2c port.\n"); | 88 | DEBUG_MSG("viafb_i2c: specify wrong i2c type.\n"); |
84 | } | 89 | } |
85 | viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val); | 90 | viafb_write_reg(adap_data->ioport_index, |
91 | adap_data->io_port, val); | ||
86 | } | 92 | } |
87 | 93 | ||
88 | int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata) | 94 | int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata) |
89 | { | 95 | { |
90 | u8 mm1[] = {0x00}; | 96 | u8 mm1[] = {0x00}; |
91 | struct i2c_msg msgs[2]; | 97 | struct i2c_msg msgs[2]; |
@@ -97,12 +103,11 @@ int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata) | |||
97 | mm1[0] = index; | 103 | mm1[0] = index; |
98 | msgs[0].len = 1; msgs[1].len = 1; | 104 | msgs[0].len = 1; msgs[1].len = 1; |
99 | msgs[0].buf = mm1; msgs[1].buf = pdata; | 105 | msgs[0].buf = mm1; msgs[1].buf = pdata; |
100 | i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, msgs, 2); | 106 | return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter, |
101 | 107 | msgs, 2); | |
102 | return 0; | ||
103 | } | 108 | } |
104 | 109 | ||
105 | int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data) | 110 | int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data) |
106 | { | 111 | { |
107 | u8 msg[2] = { index, data }; | 112 | u8 msg[2] = { index, data }; |
108 | struct i2c_msg msgs; | 113 | struct i2c_msg msgs; |
@@ -111,10 +116,11 @@ int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data) | |||
111 | msgs.addr = slave_addr / 2; | 116 | msgs.addr = slave_addr / 2; |
112 | msgs.len = 2; | 117 | msgs.len = 2; |
113 | msgs.buf = msg; | 118 | msgs.buf = msg; |
114 | return i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, &msgs, 1); | 119 | return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter, |
120 | &msgs, 1); | ||
115 | } | 121 | } |
116 | 122 | ||
117 | int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len) | 123 | int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len) |
118 | { | 124 | { |
119 | u8 mm1[] = {0x00}; | 125 | u8 mm1[] = {0x00}; |
120 | struct i2c_msg msgs[2]; | 126 | struct i2c_msg msgs[2]; |
@@ -125,53 +131,88 @@ int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len) | |||
125 | mm1[0] = index; | 131 | mm1[0] = index; |
126 | msgs[0].len = 1; msgs[1].len = buff_len; | 132 | msgs[0].len = 1; msgs[1].len = buff_len; |
127 | msgs[0].buf = mm1; msgs[1].buf = buff; | 133 | msgs[0].buf = mm1; msgs[1].buf = buff; |
128 | i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, msgs, 2); | 134 | return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter, |
129 | return 0; | 135 | msgs, 2); |
130 | } | 136 | } |
131 | 137 | ||
132 | int viafb_create_i2c_bus(void *viapar) | 138 | static int create_i2c_bus(struct i2c_adapter *adapter, |
139 | struct i2c_algo_bit_data *algo, | ||
140 | struct via_i2c_adap_cfg *adap_cfg, | ||
141 | struct pci_dev *pdev) | ||
133 | { | 142 | { |
134 | int ret; | 143 | printk(KERN_DEBUG "viafb: creating bus adap=0x%p, algo_bit_data=0x%p, adap_cfg=0x%p\n", adapter, algo, adap_cfg); |
135 | struct via_i2c_stuff *i2c_stuff = | 144 | |
136 | &((struct viafb_par *)viapar)->shared->i2c_stuff; | 145 | algo->setsda = via_i2c_setsda; |
137 | 146 | algo->setscl = via_i2c_setscl; | |
138 | strcpy(i2c_stuff->adapter.name, "via_i2c"); | 147 | algo->getsda = via_i2c_getsda; |
139 | i2c_stuff->i2c_port = 0x0; | 148 | algo->getscl = via_i2c_getscl; |
140 | i2c_stuff->adapter.owner = THIS_MODULE; | 149 | algo->udelay = 40; |
141 | i2c_stuff->adapter.id = 0x01FFFF; | 150 | algo->timeout = 20; |
142 | i2c_stuff->adapter.class = 0; | 151 | algo->data = adap_cfg; |
143 | i2c_stuff->adapter.algo_data = &i2c_stuff->algo; | 152 | |
144 | i2c_stuff->adapter.dev.parent = NULL; | 153 | sprintf(adapter->name, "viafb i2c io_port idx 0x%02x", |
145 | i2c_stuff->algo.setsda = via_i2c_setsda; | 154 | adap_cfg->ioport_index); |
146 | i2c_stuff->algo.setscl = via_i2c_setscl; | 155 | adapter->owner = THIS_MODULE; |
147 | i2c_stuff->algo.getsda = via_i2c_getsda; | 156 | adapter->id = 0x01FFFF; |
148 | i2c_stuff->algo.getscl = via_i2c_getscl; | 157 | adapter->class = I2C_CLASS_DDC; |
149 | i2c_stuff->algo.udelay = 40; | 158 | adapter->algo_data = algo; |
150 | i2c_stuff->algo.timeout = 20; | 159 | if (pdev) |
151 | i2c_stuff->algo.data = i2c_stuff; | 160 | adapter->dev.parent = &pdev->dev; |
152 | 161 | else | |
153 | i2c_set_adapdata(&i2c_stuff->adapter, i2c_stuff); | 162 | adapter->dev.parent = NULL; |
163 | /* i2c_set_adapdata(adapter, adap_cfg); */ | ||
154 | 164 | ||
155 | /* Raise SCL and SDA */ | 165 | /* Raise SCL and SDA */ |
156 | i2c_stuff->i2c_port = I2CPORTINDEX; | 166 | via_i2c_setsda(adap_cfg, 1); |
157 | via_i2c_setsda(i2c_stuff, 1); | 167 | via_i2c_setscl(adap_cfg, 1); |
158 | via_i2c_setscl(i2c_stuff, 1); | ||
159 | |||
160 | i2c_stuff->i2c_port = GPIOPORTINDEX; | ||
161 | via_i2c_setsda(i2c_stuff, 1); | ||
162 | via_i2c_setscl(i2c_stuff, 1); | ||
163 | udelay(20); | 168 | udelay(20); |
164 | 169 | ||
165 | ret = i2c_bit_add_bus(&i2c_stuff->adapter); | 170 | return i2c_bit_add_bus(adapter); |
166 | if (ret == 0) | 171 | } |
167 | DEBUG_MSG("I2C bus %s registered.\n", i2c_stuff->adapter.name); | 172 | |
168 | else | 173 | static struct via_i2c_adap_cfg adap_configs[] = { |
169 | DEBUG_MSG("Failed to register I2C bus %s.\n", | 174 | [VIA_I2C_ADAP_26] = { VIA_I2C_I2C, VIASR, 0x26 }, |
170 | i2c_stuff->adapter.name); | 175 | [VIA_I2C_ADAP_31] = { VIA_I2C_I2C, VIASR, 0x31 }, |
171 | return ret; | 176 | [VIA_I2C_ADAP_25] = { VIA_I2C_GPIO, VIASR, 0x25 }, |
177 | [VIA_I2C_ADAP_2C] = { VIA_I2C_GPIO, VIASR, 0x2c }, | ||
178 | [VIA_I2C_ADAP_3D] = { VIA_I2C_GPIO, VIASR, 0x3d }, | ||
179 | { 0, 0, 0 } | ||
180 | }; | ||
181 | |||
182 | int viafb_create_i2c_busses(struct viafb_par *viapar) | ||
183 | { | ||
184 | int i, ret; | ||
185 | |||
186 | for (i = 0; i < VIAFB_NUM_I2C; i++) { | ||
187 | struct via_i2c_adap_cfg *adap_cfg = &adap_configs[i]; | ||
188 | struct via_i2c_stuff *i2c_stuff = &viapar->shared->i2c_stuff[i]; | ||
189 | |||
190 | if (adap_cfg->type == 0) | ||
191 | break; | ||
192 | |||
193 | ret = create_i2c_bus(&i2c_stuff->adapter, | ||
194 | &i2c_stuff->algo, adap_cfg, | ||
195 | NULL); /* FIXME: PCIDEV */ | ||
196 | if (ret < 0) { | ||
197 | printk(KERN_ERR "viafb: cannot create i2c bus %u:%d\n", | ||
198 | i, ret); | ||
199 | /* FIXME: properly release previous busses */ | ||
200 | return ret; | ||
201 | } | ||
202 | } | ||
203 | |||
204 | return 0; | ||
172 | } | 205 | } |
173 | 206 | ||
174 | void viafb_delete_i2c_buss(void *par) | 207 | void viafb_delete_i2c_busses(struct viafb_par *par) |
175 | { | 208 | { |
176 | i2c_del_adapter(&((struct viafb_par *)par)->shared->i2c_stuff.adapter); | 209 | int i; |
210 | |||
211 | for (i = 0; i < ARRAY_SIZE(par->shared->i2c_stuff); i++) { | ||
212 | struct via_i2c_stuff *i2c_stuff = &par->shared->i2c_stuff[i]; | ||
213 | /* only remove those entries in the array that we've | ||
214 | * actually used (and thus initialized algo_data) */ | ||
215 | if (i2c_stuff->adapter.algo_data == &i2c_stuff->algo) | ||
216 | i2c_del_adapter(&i2c_stuff->adapter); | ||
217 | } | ||
177 | } | 218 | } |
diff --git a/drivers/video/via/via_i2c.h b/drivers/video/via/via_i2c.h index 3a13242a3152..00ed97886842 100644 --- a/drivers/video/via/via_i2c.h +++ b/drivers/video/via/via_i2c.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. | 2 | * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved. |
3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. | 3 | * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. |
4 | 4 | ||
5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
@@ -24,23 +24,38 @@ | |||
24 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
25 | #include <linux/i2c-algo-bit.h> | 25 | #include <linux/i2c-algo-bit.h> |
26 | 26 | ||
27 | enum via_i2c_type { | ||
28 | VIA_I2C_NONE, | ||
29 | VIA_I2C_I2C, | ||
30 | VIA_I2C_GPIO, | ||
31 | }; | ||
32 | |||
33 | /* private data for each adapter */ | ||
34 | struct via_i2c_adap_cfg { | ||
35 | enum via_i2c_type type; | ||
36 | u_int16_t io_port; | ||
37 | u_int8_t ioport_index; | ||
38 | }; | ||
39 | |||
27 | struct via_i2c_stuff { | 40 | struct via_i2c_stuff { |
28 | u16 i2c_port; /* GPIO or I2C port */ | 41 | u16 i2c_port; /* GPIO or I2C port */ |
29 | struct i2c_adapter adapter; | 42 | struct i2c_adapter adapter; |
30 | struct i2c_algo_bit_data algo; | 43 | struct i2c_algo_bit_data algo; |
31 | }; | 44 | }; |
32 | 45 | ||
33 | #define I2CPORT 0x3c4 | 46 | enum viafb_i2c_adap { |
34 | #define I2CPORTINDEX 0x31 | 47 | VIA_I2C_ADAP_26, |
35 | #define GPIOPORT 0x3C4 | 48 | VIA_I2C_ADAP_31, |
36 | #define GPIOPORTINDEX 0x2C | 49 | VIA_I2C_ADAP_25, |
37 | #define I2C_BUS 1 | 50 | VIA_I2C_ADAP_2C, |
38 | #define GPIO_BUS 2 | 51 | VIA_I2C_ADAP_3D, |
39 | #define DELAYPORT 0x3C3 | 52 | }; |
40 | 53 | ||
41 | int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata); | 54 | int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata); |
42 | int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data); | 55 | int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data); |
43 | int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len); | 56 | int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len); |
44 | int viafb_create_i2c_bus(void *par); | 57 | |
45 | void viafb_delete_i2c_buss(void *par); | 58 | struct viafb_par; |
59 | int viafb_create_i2c_busses(struct viafb_par *par); | ||
60 | void viafb_delete_i2c_busses(struct viafb_par *par); | ||
46 | #endif /* __VIA_I2C_H__ */ | 61 | #endif /* __VIA_I2C_H__ */ |
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 8955ab4caac8..fa1004997c63 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c | |||
@@ -1775,7 +1775,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, | |||
1775 | viafb_dual_fb = 0; | 1775 | viafb_dual_fb = 0; |
1776 | 1776 | ||
1777 | /* Set up I2C bus stuff */ | 1777 | /* Set up I2C bus stuff */ |
1778 | rc = viafb_create_i2c_bus(viaparinfo); | 1778 | rc = viafb_create_i2c_busses(viaparinfo); |
1779 | if (rc) | 1779 | if (rc) |
1780 | goto out_fb_release; | 1780 | goto out_fb_release; |
1781 | 1781 | ||
@@ -1964,7 +1964,7 @@ out_fb1_release: | |||
1964 | out_unmap_screen: | 1964 | out_unmap_screen: |
1965 | iounmap(viafbinfo->screen_base); | 1965 | iounmap(viafbinfo->screen_base); |
1966 | out_delete_i2c: | 1966 | out_delete_i2c: |
1967 | viafb_delete_i2c_buss(viaparinfo); | 1967 | viafb_delete_i2c_busses(viaparinfo); |
1968 | out_fb_release: | 1968 | out_fb_release: |
1969 | framebuffer_release(viafbinfo); | 1969 | framebuffer_release(viafbinfo); |
1970 | return rc; | 1970 | return rc; |
@@ -1980,7 +1980,7 @@ static void __devexit via_pci_remove(struct pci_dev *pdev) | |||
1980 | iounmap((void *)viafbinfo->screen_base); | 1980 | iounmap((void *)viafbinfo->screen_base); |
1981 | iounmap(viaparinfo->shared->engine_mmio); | 1981 | iounmap(viaparinfo->shared->engine_mmio); |
1982 | 1982 | ||
1983 | viafb_delete_i2c_buss(viaparinfo); | 1983 | viafb_delete_i2c_busses(viaparinfo); |
1984 | 1984 | ||
1985 | framebuffer_release(viafbinfo); | 1985 | framebuffer_release(viafbinfo); |
1986 | if (viafb_dual_fb) | 1986 | if (viafb_dual_fb) |
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index 61b5953cd159..4bc00ec8fb1c 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h | |||
@@ -37,11 +37,13 @@ | |||
37 | #define VERSION_OS 0 /* 0: for 32 bits OS, 1: for 64 bits OS */ | 37 | #define VERSION_OS 0 /* 0: for 32 bits OS, 1: for 64 bits OS */ |
38 | #define VERSION_MINOR 4 | 38 | #define VERSION_MINOR 4 |
39 | 39 | ||
40 | #define VIAFB_NUM_I2C 5 | ||
41 | |||
40 | struct viafb_shared { | 42 | struct viafb_shared { |
41 | struct proc_dir_entry *proc_entry; /*viafb proc entry */ | 43 | struct proc_dir_entry *proc_entry; /*viafb proc entry */ |
42 | 44 | ||
43 | /* I2C stuff */ | 45 | /* I2C stuff */ |
44 | struct via_i2c_stuff i2c_stuff; | 46 | struct via_i2c_stuff i2c_stuff[VIAFB_NUM_I2C]; |
45 | 47 | ||
46 | /* All the information will be needed to set engine */ | 48 | /* All the information will be needed to set engine */ |
47 | struct tmds_setting_information tmds_setting_info; | 49 | struct tmds_setting_information tmds_setting_info; |
diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c index a6b37494e79a..4589c6e73c5d 100644 --- a/drivers/video/via/vt1636.c +++ b/drivers/video/via/vt1636.c | |||
@@ -27,9 +27,8 @@ u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information | |||
27 | { | 27 | { |
28 | u8 data; | 28 | u8 data; |
29 | 29 | ||
30 | viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; | 30 | viafb_i2c_readbyte(plvds_chip_info->i2c_port, |
31 | viafb_i2c_readbyte(plvds_chip_info->lvds_chip_slave_addr, index, &data); | 31 | plvds_chip_info->lvds_chip_slave_addr, index, &data); |
32 | |||
33 | return data; | 32 | return data; |
34 | } | 33 | } |
35 | 34 | ||
@@ -39,14 +38,13 @@ void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information | |||
39 | { | 38 | { |
40 | int index, data; | 39 | int index, data; |
41 | 40 | ||
42 | viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; | ||
43 | |||
44 | index = io_data.Index; | 41 | index = io_data.Index; |
45 | data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info, | 42 | data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info, |
46 | index); | 43 | index); |
47 | data = (data & (~io_data.Mask)) | io_data.Data; | 44 | data = (data & (~io_data.Mask)) | io_data.Data; |
48 | 45 | ||
49 | viafb_i2c_writebyte(plvds_chip_info->lvds_chip_slave_addr, index, data); | 46 | viafb_i2c_writebyte(plvds_chip_info->i2c_port, |
47 | plvds_chip_info->lvds_chip_slave_addr, index, data); | ||
50 | } | 48 | } |
51 | 49 | ||
52 | void viafb_init_lvds_vt1636(struct lvds_setting_information | 50 | void viafb_init_lvds_vt1636(struct lvds_setting_information |
@@ -159,7 +157,7 @@ void viafb_disable_lvds_vt1636(struct lvds_setting_information | |||
159 | } | 157 | } |
160 | } | 158 | } |
161 | 159 | ||
162 | bool viafb_lvds_identify_vt1636(void) | 160 | bool viafb_lvds_identify_vt1636(u8 i2c_adapter) |
163 | { | 161 | { |
164 | u8 Buffer[2]; | 162 | u8 Buffer[2]; |
165 | 163 | ||
@@ -170,23 +168,23 @@ bool viafb_lvds_identify_vt1636(void) | |||
170 | VT1636_LVDS_I2C_ADDR; | 168 | VT1636_LVDS_I2C_ADDR; |
171 | 169 | ||
172 | /* Check vendor ID first: */ | 170 | /* Check vendor ID first: */ |
173 | viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. | 171 | viafb_i2c_readbyte(i2c_adapter, |
174 | lvds_chip_slave_addr, | 172 | (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr, |
175 | 0x00, &Buffer[0]); | 173 | 0x00, &Buffer[0]); |
176 | viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. | 174 | viafb_i2c_readbyte(i2c_adapter, |
177 | lvds_chip_slave_addr, | 175 | (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr, |
178 | 0x01, &Buffer[1]); | 176 | 0x01, &Buffer[1]); |
179 | 177 | ||
180 | if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11))) | 178 | if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11))) |
181 | return false; | 179 | return false; |
182 | 180 | ||
183 | /* Check Chip ID: */ | 181 | /* Check Chip ID: */ |
184 | viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. | 182 | viafb_i2c_readbyte(i2c_adapter, |
185 | lvds_chip_slave_addr, | 183 | (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr, |
186 | 0x02, &Buffer[0]); | 184 | 0x02, &Buffer[0]); |
187 | viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. | 185 | viafb_i2c_readbyte(i2c_adapter, |
188 | lvds_chip_slave_addr, | 186 | (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr, |
189 | 0x03, &Buffer[1]); | 187 | 0x03, &Buffer[1]); |
190 | if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) { | 188 | if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) { |
191 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = | 189 | viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = |
192 | VT1636_LVDS; | 190 | VT1636_LVDS; |
diff --git a/drivers/video/via/vt1636.h b/drivers/video/via/vt1636.h index 2a150c58c7ed..4c1314e57468 100644 --- a/drivers/video/via/vt1636.h +++ b/drivers/video/via/vt1636.h | |||
@@ -22,7 +22,7 @@ | |||
22 | #ifndef _VT1636_H_ | 22 | #ifndef _VT1636_H_ |
23 | #define _VT1636_H_ | 23 | #define _VT1636_H_ |
24 | #include "chip.h" | 24 | #include "chip.h" |
25 | bool viafb_lvds_identify_vt1636(void); | 25 | bool viafb_lvds_identify_vt1636(u8 i2c_adapter); |
26 | void viafb_init_lvds_vt1636(struct lvds_setting_information | 26 | void viafb_init_lvds_vt1636(struct lvds_setting_information |
27 | *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); | 27 | *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); |
28 | void viafb_enable_lvds_vt1636(struct lvds_setting_information | 28 | void viafb_enable_lvds_vt1636(struct lvds_setting_information |