aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/busses/i2c-i801.c50
-rw-r--r--drivers/input/misc/apanel.c81
2 files changed, 76 insertions, 55 deletions
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 5123eb69a971..526625eaa84b 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -64,7 +64,7 @@
64#include <linux/init.h> 64#include <linux/init.h>
65#include <linux/i2c.h> 65#include <linux/i2c.h>
66#include <linux/acpi.h> 66#include <linux/acpi.h>
67#include <asm/io.h> 67#include <linux/io.h>
68 68
69/* I801 SMBus address offsets */ 69/* I801 SMBus address offsets */
70#define SMBHSTSTS (0 + i801_smba) 70#define SMBHSTSTS (0 + i801_smba)
@@ -583,6 +583,40 @@ static struct pci_device_id i801_ids[] = {
583 583
584MODULE_DEVICE_TABLE (pci, i801_ids); 584MODULE_DEVICE_TABLE (pci, i801_ids);
585 585
586#if defined CONFIG_INPUT_APANEL || defined CONFIG_INPUT_APANEL_MODULE
587static unsigned char apanel_addr;
588
589/* Scan the system ROM for the signature "FJKEYINF" */
590static __init const void __iomem *bios_signature(const void __iomem *bios)
591{
592 ssize_t offset;
593 const unsigned char signature[] = "FJKEYINF";
594
595 for (offset = 0; offset < 0x10000; offset += 0x10) {
596 if (check_signature(bios + offset, signature,
597 sizeof(signature)-1))
598 return bios + offset;
599 }
600 return NULL;
601}
602
603static void __init input_apanel_init(void)
604{
605 void __iomem *bios;
606 const void __iomem *p;
607
608 bios = ioremap(0xF0000, 0x10000); /* Can't fail */
609 p = bios_signature(bios);
610 if (p) {
611 /* just use the first address */
612 apanel_addr = readb(p + 8 + 3) >> 1;
613 }
614 iounmap(bios);
615}
616#else
617static void __init input_apanel_init(void) {}
618#endif
619
586static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) 620static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
587{ 621{
588 unsigned char temp; 622 unsigned char temp;
@@ -667,6 +701,19 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
667 dev_err(&dev->dev, "Failed to add SMBus adapter\n"); 701 dev_err(&dev->dev, "Failed to add SMBus adapter\n");
668 goto exit_release; 702 goto exit_release;
669 } 703 }
704
705 /* Register optional slaves */
706#if defined CONFIG_INPUT_APANEL || defined CONFIG_INPUT_APANEL_MODULE
707 if (apanel_addr) {
708 struct i2c_board_info info;
709
710 memset(&info, 0, sizeof(struct i2c_board_info));
711 info.addr = apanel_addr;
712 strlcpy(info.type, "fujitsu_apanel", I2C_NAME_SIZE);
713 i2c_new_device(&i801_adapter, &info);
714 }
715#endif
716
670 return 0; 717 return 0;
671 718
672exit_release: 719exit_release:
@@ -717,6 +764,7 @@ static struct pci_driver i801_driver = {
717 764
718static int __init i2c_i801_init(void) 765static int __init i2c_i801_init(void)
719{ 766{
767 input_apanel_init();
720 return pci_register_driver(&i801_driver); 768 return pci_register_driver(&i801_driver);
721} 769}
722 770
diff --git a/drivers/input/misc/apanel.c b/drivers/input/misc/apanel.c
index d82f7f727f7a..71b82434264d 100644
--- a/drivers/input/misc/apanel.c
+++ b/drivers/input/misc/apanel.c
@@ -57,7 +57,7 @@ static enum apanel_chip device_chip[APANEL_DEV_MAX];
57 57
58struct apanel { 58struct apanel {
59 struct input_polled_dev *ipdev; 59 struct input_polled_dev *ipdev;
60 struct i2c_client client; 60 struct i2c_client *client;
61 unsigned short keymap[MAX_PANEL_KEYS]; 61 unsigned short keymap[MAX_PANEL_KEYS];
62 u16 nkeys; 62 u16 nkeys;
63 u16 led_bits; 63 u16 led_bits;
@@ -66,16 +66,7 @@ struct apanel {
66}; 66};
67 67
68 68
69static int apanel_probe(struct i2c_adapter *, int, int); 69static int apanel_probe(struct i2c_client *, const struct i2c_device_id *);
70
71/* for now, we only support one address */
72static unsigned short normal_i2c[] = {0, I2C_CLIENT_END};
73static unsigned short ignore = I2C_CLIENT_END;
74static struct i2c_client_address_data addr_data = {
75 .normal_i2c = normal_i2c,
76 .probe = &ignore,
77 .ignore = &ignore,
78};
79 70
80static void report_key(struct input_dev *input, unsigned keycode) 71static void report_key(struct input_dev *input, unsigned keycode)
81{ 72{
@@ -103,12 +94,12 @@ static void apanel_poll(struct input_polled_dev *ipdev)
103 s32 data; 94 s32 data;
104 int i; 95 int i;
105 96
106 data = i2c_smbus_read_word_data(&ap->client, cmd); 97 data = i2c_smbus_read_word_data(ap->client, cmd);
107 if (data < 0) 98 if (data < 0)
108 return; /* ignore errors (due to ACPI??) */ 99 return; /* ignore errors (due to ACPI??) */
109 100
110 /* write back to clear latch */ 101 /* write back to clear latch */
111 i2c_smbus_write_word_data(&ap->client, cmd, 0); 102 i2c_smbus_write_word_data(ap->client, cmd, 0);
112 103
113 if (!data) 104 if (!data)
114 return; 105 return;
@@ -124,7 +115,7 @@ static void led_update(struct work_struct *work)
124{ 115{
125 struct apanel *ap = container_of(work, struct apanel, led_work); 116 struct apanel *ap = container_of(work, struct apanel, led_work);
126 117
127 i2c_smbus_write_word_data(&ap->client, 0x10, ap->led_bits); 118 i2c_smbus_write_word_data(ap->client, 0x10, ap->led_bits);
128} 119}
129 120
130static void mail_led_set(struct led_classdev *led, 121static void mail_led_set(struct led_classdev *led,
@@ -140,7 +131,7 @@ static void mail_led_set(struct led_classdev *led,
140 schedule_work(&ap->led_work); 131 schedule_work(&ap->led_work);
141} 132}
142 133
143static int apanel_detach_client(struct i2c_client *client) 134static int apanel_remove(struct i2c_client *client)
144{ 135{
145 struct apanel *ap = i2c_get_clientdata(client); 136 struct apanel *ap = i2c_get_clientdata(client);
146 137
@@ -148,43 +139,33 @@ static int apanel_detach_client(struct i2c_client *client)
148 led_classdev_unregister(&ap->mail_led); 139 led_classdev_unregister(&ap->mail_led);
149 140
150 input_unregister_polled_device(ap->ipdev); 141 input_unregister_polled_device(ap->ipdev);
151 i2c_detach_client(&ap->client);
152 input_free_polled_device(ap->ipdev); 142 input_free_polled_device(ap->ipdev);
153 143
154 return 0; 144 return 0;
155} 145}
156 146
157/* Function is invoked for every i2c adapter. */
158static int apanel_attach_adapter(struct i2c_adapter *adap)
159{
160 dev_dbg(&adap->dev, APANEL ": attach adapter id=%d\n", adap->id);
161
162 /* Our device is connected only to i801 on laptop */
163 if (adap->id != I2C_HW_SMBUS_I801)
164 return -ENODEV;
165
166 return i2c_probe(adap, &addr_data, apanel_probe);
167}
168
169static void apanel_shutdown(struct i2c_client *client) 147static void apanel_shutdown(struct i2c_client *client)
170{ 148{
171 apanel_detach_client(client); 149 apanel_remove(client);
172} 150}
173 151
152static struct i2c_device_id apanel_id[] = {
153 { "fujitsu_apanel", 0 },
154 { }
155};
156MODULE_DEVICE_TABLE(i2c, apanel_id);
157
174static struct i2c_driver apanel_driver = { 158static struct i2c_driver apanel_driver = {
175 .driver = { 159 .driver = {
176 .name = APANEL, 160 .name = APANEL,
177 }, 161 },
178 .attach_adapter = &apanel_attach_adapter, 162 .probe = &apanel_probe,
179 .detach_client = &apanel_detach_client, 163 .remove = &apanel_remove,
180 .shutdown = &apanel_shutdown, 164 .shutdown = &apanel_shutdown,
165 .id_table = apanel_id,
181}; 166};
182 167
183static struct apanel apanel = { 168static struct apanel apanel = {
184 .client = {
185 .driver = &apanel_driver,
186 .name = APANEL,
187 },
188 .keymap = { 169 .keymap = {
189 [0] = KEY_MAIL, 170 [0] = KEY_MAIL,
190 [1] = KEY_WWW, 171 [1] = KEY_WWW,
@@ -204,7 +185,8 @@ static struct apanel apanel = {
204}; 185};
205 186
206/* NB: Only one panel on the i2c. */ 187/* NB: Only one panel on the i2c. */
207static int apanel_probe(struct i2c_adapter *bus, int address, int kind) 188static int apanel_probe(struct i2c_client *client,
189 const struct i2c_device_id *id)
208{ 190{
209 struct apanel *ap; 191 struct apanel *ap;
210 struct input_polled_dev *ipdev; 192 struct input_polled_dev *ipdev;
@@ -212,9 +194,6 @@ static int apanel_probe(struct i2c_adapter *bus, int address, int kind)
212 u8 cmd = device_chip[APANEL_DEV_APPBTN] == CHIP_OZ992C ? 0 : 8; 194 u8 cmd = device_chip[APANEL_DEV_APPBTN] == CHIP_OZ992C ? 0 : 8;
213 int i, err = -ENOMEM; 195 int i, err = -ENOMEM;
214 196
215 dev_dbg(&bus->dev, APANEL ": probe adapter %p addr %d kind %d\n",
216 bus, address, kind);
217
218 ap = &apanel; 197 ap = &apanel;
219 198
220 ipdev = input_allocate_polled_device(); 199 ipdev = input_allocate_polled_device();
@@ -222,18 +201,13 @@ static int apanel_probe(struct i2c_adapter *bus, int address, int kind)
222 goto out1; 201 goto out1;
223 202
224 ap->ipdev = ipdev; 203 ap->ipdev = ipdev;
225 ap->client.adapter = bus; 204 ap->client = client;
226 ap->client.addr = address;
227
228 i2c_set_clientdata(&ap->client, ap);
229 205
230 err = i2c_attach_client(&ap->client); 206 i2c_set_clientdata(client, ap);
231 if (err)
232 goto out2;
233 207
234 err = i2c_smbus_write_word_data(&ap->client, cmd, 0); 208 err = i2c_smbus_write_word_data(client, cmd, 0);
235 if (err) { 209 if (err) {
236 dev_warn(&ap->client.dev, APANEL ": smbus write error %d\n", 210 dev_warn(&client->dev, APANEL ": smbus write error %d\n",
237 err); 211 err);
238 goto out3; 212 goto out3;
239 } 213 }
@@ -246,7 +220,7 @@ static int apanel_probe(struct i2c_adapter *bus, int address, int kind)
246 idev->name = APANEL_NAME " buttons"; 220 idev->name = APANEL_NAME " buttons";
247 idev->phys = "apanel/input0"; 221 idev->phys = "apanel/input0";
248 idev->id.bustype = BUS_HOST; 222 idev->id.bustype = BUS_HOST;
249 idev->dev.parent = &ap->client.dev; 223 idev->dev.parent = &client->dev;
250 224
251 set_bit(EV_KEY, idev->evbit); 225 set_bit(EV_KEY, idev->evbit);
252 226
@@ -264,7 +238,7 @@ static int apanel_probe(struct i2c_adapter *bus, int address, int kind)
264 238
265 INIT_WORK(&ap->led_work, led_update); 239 INIT_WORK(&ap->led_work, led_update);
266 if (device_chip[APANEL_DEV_LED] != CHIP_NONE) { 240 if (device_chip[APANEL_DEV_LED] != CHIP_NONE) {
267 err = led_classdev_register(&ap->client.dev, &ap->mail_led); 241 err = led_classdev_register(&client->dev, &ap->mail_led);
268 if (err) 242 if (err)
269 goto out4; 243 goto out4;
270 } 244 }
@@ -273,8 +247,6 @@ static int apanel_probe(struct i2c_adapter *bus, int address, int kind)
273out4: 247out4:
274 input_unregister_polled_device(ipdev); 248 input_unregister_polled_device(ipdev);
275out3: 249out3:
276 i2c_detach_client(&ap->client);
277out2:
278 input_free_polled_device(ipdev); 250 input_free_polled_device(ipdev);
279out1: 251out1:
280 return err; 252 return err;
@@ -301,6 +273,7 @@ static int __init apanel_init(void)
301 void __iomem *bios; 273 void __iomem *bios;
302 const void __iomem *p; 274 const void __iomem *p;
303 u8 devno; 275 u8 devno;
276 unsigned char i2c_addr;
304 int found = 0; 277 int found = 0;
305 278
306 bios = ioremap(0xF0000, 0x10000); /* Can't fail */ 279 bios = ioremap(0xF0000, 0x10000); /* Can't fail */
@@ -313,7 +286,7 @@ static int __init apanel_init(void)
313 286
314 /* just use the first address */ 287 /* just use the first address */
315 p += 8; 288 p += 8;
316 normal_i2c[0] = readb(p+3) >> 1; 289 i2c_addr = readb(p + 3) >> 1;
317 290
318 for ( ; (devno = readb(p)) & 0x7f; p += 4) { 291 for ( ; (devno = readb(p)) & 0x7f; p += 4) {
319 unsigned char method, slave, chip; 292 unsigned char method, slave, chip;
@@ -322,7 +295,7 @@ static int __init apanel_init(void)
322 chip = readb(p + 2); 295 chip = readb(p + 2);
323 slave = readb(p + 3) >> 1; 296 slave = readb(p + 3) >> 1;
324 297
325 if (slave != normal_i2c[0]) { 298 if (slave != i2c_addr) {
326 pr_notice(APANEL ": only one SMBus slave " 299 pr_notice(APANEL ": only one SMBus slave "
327 "address supported, skiping device...\n"); 300 "address supported, skiping device...\n");
328 continue; 301 continue;