usb: gadget: m66592-udc: add pullup function
[zen-stable.git] / drivers / staging / nvec / nvec.c
blob1a94364c48b587f1139e1ad15c386c1351525d18
1 // #define DEBUG
3 /* ToDo list (incomplete, unorderd)
4 - convert mouse, keyboard, and power to platform devices
5 */
7 #include <asm/io.h>
8 #include <asm/irq.h>
9 #include <linux/completion.h>
10 #include <linux/interrupt.h>
11 #include <linux/irq.h>
12 #include <linux/slab.h>
13 #include <linux/gpio.h>
14 #include <linux/serio.h>
15 #include <linux/delay.h>
16 #include <linux/input.h>
17 #include <linux/workqueue.h>
18 #include <linux/clk.h>
19 #include <mach/iomap.h>
20 #include <mach/clk.h>
21 #include <linux/semaphore.h>
22 #include <linux/list.h>
23 #include <linux/notifier.h>
24 #include <linux/workqueue.h>
25 #include <linux/platform_device.h>
26 #include "nvec.h"
28 static unsigned char EC_DISABLE_EVENT_REPORTING[] = {'\x04','\x00','\x00'};
29 static unsigned char EC_ENABLE_EVENT_REPORTING[] = {'\x04','\x00','\x01'};
30 static unsigned char EC_GET_FIRMWARE_VERSION[] = {'\x07','\x15'};
32 static struct nvec_chip *nvec_power_handle;
34 int nvec_register_notifier(struct nvec_chip *nvec, struct notifier_block *nb,
35 unsigned int events)
37 return atomic_notifier_chain_register(&nvec->notifier_list, nb);
39 EXPORT_SYMBOL_GPL(nvec_register_notifier);
41 static int nvec_status_notifier(struct notifier_block *nb, unsigned long event_type,
42 void *data)
44 unsigned char *msg = (unsigned char *)data;
45 int i;
47 if(event_type != NVEC_CNTL)
48 return NOTIFY_DONE;
50 printk("unhandled msg type %ld, payload: ", event_type);
51 for (i = 0; i < msg[1]; i++)
52 printk("%0x ", msg[i+2]);
53 printk("\n");
55 return NOTIFY_OK;
58 void nvec_write_async(struct nvec_chip *nvec, unsigned char *data, short size)
60 struct nvec_msg *msg = kzalloc(sizeof(struct nvec_msg), GFP_NOWAIT);
62 msg->data = kzalloc(size, GFP_NOWAIT);
63 msg->data[0] = size;
64 memcpy(msg->data + 1, data, size);
65 msg->size = size + 1;
66 msg->pos = 0;
67 INIT_LIST_HEAD(&msg->node);
69 list_add_tail(&msg->node, &nvec->tx_data);
71 gpio_set_value(nvec->gpio, 0);
73 EXPORT_SYMBOL(nvec_write_async);
75 static void nvec_request_master(struct work_struct *work)
77 struct nvec_chip *nvec = container_of(work, struct nvec_chip, tx_work);
79 if(!list_empty(&nvec->tx_data)) {
80 gpio_set_value(nvec->gpio, 0);
84 static int parse_msg(struct nvec_chip *nvec, struct nvec_msg *msg)
86 int i;
88 if((msg->data[0] & 1<<7) == 0 && msg->data[3]) {
89 dev_err(nvec->dev, "ec responded %02x %02x %02x %02x\n", msg->data[0],
90 msg->data[1], msg->data[2], msg->data[3]);
91 return -EINVAL;
94 if ((msg->data[0] >> 7 ) == 1 && (msg->data[0] & 0x0f) == 5)
96 dev_warn(nvec->dev, "ec system event ");
97 for (i=0; i < msg->data[1]; i++)
98 dev_warn(nvec->dev, "%02x ", msg->data[2+i]);
99 dev_warn(nvec->dev, "\n");
102 atomic_notifier_call_chain(&nvec->notifier_list, msg->data[0] & 0x8f, msg->data);
104 return 0;
107 static struct nvec_msg *nvec_write_sync(struct nvec_chip *nvec, unsigned char *data, short size)
109 down(&nvec->sync_write_mutex);
111 nvec->sync_write_pending = (data[1] << 8) + data[0];
112 nvec_write_async(nvec, data, size);
114 dev_dbg(nvec->dev, "nvec_sync_write: 0x%04x\n", nvec->sync_write_pending);
115 wait_for_completion(&nvec->sync_write);
116 dev_dbg(nvec->dev, "nvec_sync_write: pong!\n");
118 up(&nvec->sync_write_mutex);
120 return nvec->last_sync_msg;
123 /* RX worker */
124 static void nvec_dispatch(struct work_struct *work)
126 struct nvec_chip *nvec = container_of(work, struct nvec_chip, rx_work);
127 struct nvec_msg *msg;
129 while(!list_empty(&nvec->rx_data))
131 msg = list_first_entry(&nvec->rx_data, struct nvec_msg, node);
132 list_del_init(&msg->node);
134 if(nvec->sync_write_pending == (msg->data[2] << 8) + msg->data[0])
136 dev_dbg(nvec->dev, "sync write completed!\n");
137 nvec->sync_write_pending = 0;
138 nvec->last_sync_msg = msg;
139 complete(&nvec->sync_write);
140 } else {
141 parse_msg(nvec, msg);
142 if((!msg) || (!msg->data))
143 dev_warn(nvec->dev, "attempt access zero pointer");
144 else {
145 kfree(msg->data);
146 kfree(msg);
152 static irqreturn_t i2c_interrupt(int irq, void *dev)
154 unsigned long status;
155 unsigned long received;
156 unsigned char to_send;
157 struct nvec_msg *msg;
158 struct nvec_chip *nvec = (struct nvec_chip *)dev;
159 unsigned char *i2c_regs = nvec->i2c_regs;
161 status = readl(i2c_regs + I2C_SL_STATUS);
163 if(!(status & I2C_SL_IRQ))
165 dev_warn(nvec->dev, "nvec Spurious IRQ\n");
166 //Yup, handled. ahum.
167 goto handled;
169 if(status & END_TRANS && !(status & RCVD))
171 //Reenable IRQ only when even has been sent
172 //printk("Write sequence ended !\n");
173 //parse_msg(nvec);
174 nvec->state = NVEC_WAIT;
175 if(nvec->rx->size > 1)
177 list_add_tail(&nvec->rx->node, &nvec->rx_data);
178 schedule_work(&nvec->rx_work);
179 } else {
180 kfree(nvec->rx->data);
181 kfree(nvec->rx);
183 return IRQ_HANDLED;
184 } else if(status & RNW)
186 // Work around for AP20 New Slave Hw Bug. Give 1us extra.
187 // nvec/smbus/nvec_i2c_transport.c in NV`s crap for reference
188 if(status & RCVD)
189 udelay(3);
191 if(status & RCVD)
193 nvec->state = NVEC_WRITE;
194 //Master wants something from us. New communication
195 // dev_dbg(nvec->dev, "New read comm!\n");
196 } else {
197 //Master wants something from us from a communication we've already started
198 // dev_dbg(nvec->dev, "Read comm cont !\n");
200 //if(msg_pos<msg_size) {
201 if(list_empty(&nvec->tx_data))
203 dev_err(nvec->dev, "nvec empty tx - sending no-op\n");
204 to_send = 0x8a;
205 nvec_write_async(nvec, "\x07\x02", 2);
206 // to_send = 0x01;
207 } else {
208 msg = list_first_entry(&nvec->tx_data, struct nvec_msg, node);
209 if(msg->pos < msg->size) {
210 to_send = msg->data[msg->pos];
211 msg->pos++;
212 } else {
213 dev_err(nvec->dev, "nvec crap! %d\n", msg->size);
214 to_send = 0x01;
217 if(msg->pos >= msg->size)
219 list_del_init(&msg->node);
220 kfree(msg->data);
221 kfree(msg);
222 schedule_work(&nvec->tx_work);
223 nvec->state = NVEC_WAIT;
226 writel(to_send, i2c_regs + I2C_SL_RCVD);
228 gpio_set_value(nvec->gpio, 1);
230 dev_dbg(nvec->dev, "nvec sent %x\n", to_send);
232 goto handled;
233 } else {
234 received = readl(i2c_regs + I2C_SL_RCVD);
235 //Workaround?
236 if(status & RCVD) {
237 writel(0, i2c_regs + I2C_SL_RCVD);
238 goto handled;
241 if (nvec->state == NVEC_WAIT)
243 nvec->state = NVEC_READ;
244 msg = kzalloc(sizeof(struct nvec_msg), GFP_NOWAIT);
245 msg->data = kzalloc(32, GFP_NOWAIT);
246 INIT_LIST_HEAD(&msg->node);
247 nvec->rx = msg;
248 } else
249 msg = nvec->rx;
251 BUG_ON(msg->pos > 32);
253 msg->data[msg->pos] = received;
254 msg->pos++;
255 msg->size = msg->pos;
256 dev_dbg(nvec->dev, "Got %02lx from Master (pos: %d)!\n", received, msg->pos);
258 handled:
259 return IRQ_HANDLED;
262 static int __devinit nvec_add_subdev(struct nvec_chip *nvec, struct nvec_subdev *subdev)
264 struct platform_device *pdev;
266 pdev = platform_device_alloc(subdev->name, subdev->id);
267 pdev->dev.parent = nvec->dev;
268 pdev->dev.platform_data = subdev->platform_data;
270 return platform_device_add(pdev);
273 static void tegra_init_i2c_slave(struct nvec_platform_data *pdata, unsigned char *i2c_regs,
274 struct clk *i2c_clk)
276 u32 val;
278 clk_enable(i2c_clk);
279 tegra_periph_reset_assert(i2c_clk);
280 udelay(2);
281 tegra_periph_reset_deassert(i2c_clk);
283 writel(pdata->i2c_addr>>1, i2c_regs + I2C_SL_ADDR1);
284 writel(0, i2c_regs + I2C_SL_ADDR2);
286 writel(0x1E, i2c_regs + I2C_SL_DELAY_COUNT);
287 val = I2C_CNFG_NEW_MASTER_SFM | I2C_CNFG_PACKET_MODE_EN |
288 (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT);
289 writel(val, i2c_regs + I2C_CNFG);
290 writel(I2C_SL_NEWL, i2c_regs + I2C_SL_CNFG);
292 clk_disable(i2c_clk);
295 static void nvec_power_off(void)
297 nvec_write_async(nvec_power_handle, EC_DISABLE_EVENT_REPORTING, 3);
298 nvec_write_async(nvec_power_handle, "\x04\x01", 2);
301 static int __devinit tegra_nvec_probe(struct platform_device *pdev)
303 int err, i, ret;
304 struct clk *i2c_clk;
305 struct nvec_platform_data *pdata = pdev->dev.platform_data;
306 struct nvec_chip *nvec;
307 struct nvec_msg *msg;
308 unsigned char *i2c_regs;
310 nvec = kzalloc(sizeof(struct nvec_chip), GFP_KERNEL);
311 if(nvec == NULL) {
312 dev_err(&pdev->dev, "failed to reserve memory\n");
313 return -ENOMEM;
315 platform_set_drvdata(pdev, nvec);
316 nvec->dev = &pdev->dev;
317 nvec->gpio = pdata->gpio;
318 nvec->irq = pdata->irq;
321 i2c_clk=clk_get_sys(NULL, "i2c");
322 if(IS_ERR_OR_NULL(i2c_clk))
323 printk(KERN_ERR"No such clock tegra-i2c.2\n");
324 else
325 clk_enable(i2c_clk);
327 i2c_regs = ioremap(pdata->base, pdata->size);
328 if(!i2c_regs) {
329 dev_err(nvec->dev, "failed to ioremap registers\n");
330 goto failed;
333 nvec->i2c_regs = i2c_regs;
335 i2c_clk = clk_get_sys(pdata->clock, NULL);
336 if(IS_ERR_OR_NULL(i2c_clk)) {
337 dev_err(nvec->dev, "failed to get clock tegra-i2c.2\n");
338 goto failed;
341 tegra_init_i2c_slave(pdata, i2c_regs, i2c_clk);
343 err = request_irq(nvec->irq, i2c_interrupt, IRQF_DISABLED, "nvec", nvec);
344 if(err) {
345 dev_err(nvec->dev, "couldn't request irq");
346 goto failed;
349 clk_enable(i2c_clk);
350 clk_set_rate(i2c_clk, 8*80000);
352 /* Set the gpio to low when we've got something to say */
353 err = gpio_request(nvec->gpio, "nvec gpio");
354 if(err < 0)
355 dev_err(nvec->dev, "couldn't request gpio\n");
357 tegra_gpio_enable(nvec->gpio);
358 gpio_direction_output(nvec->gpio, 1);
359 gpio_set_value(nvec->gpio, 1);
361 ATOMIC_INIT_NOTIFIER_HEAD(&nvec->notifier_list);
363 init_completion(&nvec->sync_write);
364 sema_init(&nvec->sync_write_mutex, 1);
365 INIT_LIST_HEAD(&nvec->tx_data);
366 INIT_LIST_HEAD(&nvec->rx_data);
367 INIT_WORK(&nvec->rx_work, nvec_dispatch);
368 INIT_WORK(&nvec->tx_work, nvec_request_master);
370 /* enable event reporting */
371 nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING,
372 sizeof(EC_ENABLE_EVENT_REPORTING));
374 nvec_kbd_init(nvec);
375 #ifdef CONFIG_SERIO_NVEC_PS2
376 nvec_ps2(nvec);
377 #endif
379 /* setup subdevs */
380 for (i = 0; i < pdata->num_subdevs; i++) {
381 ret = nvec_add_subdev(nvec, &pdata->subdevs[i]);
384 nvec->nvec_status_notifier.notifier_call = nvec_status_notifier;
385 nvec_register_notifier(nvec, &nvec->nvec_status_notifier, 0);
387 nvec_power_handle = nvec;
388 pm_power_off = nvec_power_off;
390 /* Get Firmware Version */
391 msg = nvec_write_sync(nvec, EC_GET_FIRMWARE_VERSION,
392 sizeof(EC_GET_FIRMWARE_VERSION));
394 dev_warn(nvec->dev, "ec firmware version %02x.%02x.%02x / %02x\n",
395 msg->data[4], msg->data[5], msg->data[6], msg->data[7]);
397 kfree(msg->data);
398 kfree(msg);
400 /* unmute speakers? */
401 nvec_write_async(nvec, "\x0d\x10\x59\x94", 4);
403 /* enable lid switch event */
404 nvec_write_async(nvec, "\x01\x01\x01\x00\x00\x02\x00", 7);
406 /* enable power button event */
407 nvec_write_async(nvec, "\x01\x01\x01\x00\x00\x80\x00", 7);
409 return 0;
411 failed:
412 kfree(nvec);
413 return -ENOMEM;
416 static int __devexit tegra_nvec_remove(struct platform_device *pdev)
418 // TODO: unregister
419 return 0;
422 #ifdef CONFIG_PM
424 static int tegra_nvec_suspend(struct platform_device *pdev, pm_message_t state)
426 struct nvec_chip *nvec = platform_get_drvdata(pdev);
428 dev_dbg(nvec->dev, "suspending\n");
429 nvec_write_async(nvec, EC_DISABLE_EVENT_REPORTING, 3);
430 nvec_write_async(nvec, "\x04\x02", 2);
432 return 0;
435 static int tegra_nvec_resume(struct platform_device *pdev) {
437 struct nvec_chip *nvec = platform_get_drvdata(pdev);
439 dev_dbg(nvec->dev, "resuming\n");
440 nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING, 3);
442 return 0;
445 #else
446 #define tegra_nvec_suspend NULL
447 #define tegra_nvec_resume NULL
448 #endif
450 static struct platform_driver nvec_device_driver =
452 .probe = tegra_nvec_probe,
453 .remove = __devexit_p(tegra_nvec_remove),
454 .suspend = tegra_nvec_suspend,
455 .resume = tegra_nvec_resume,
456 .driver = {
457 .name = "nvec",
458 .owner = THIS_MODULE,
462 static int __init tegra_nvec_init(void)
464 return platform_driver_register(&nvec_device_driver);
467 module_init(tegra_nvec_init);
468 MODULE_ALIAS("platform:nvec");