hh.org updates
[hh.org.git] / arch / arm / mach-pxa / asus730 / a730_ac97.c
blobbd89f5e7e86d8fad7a0c6e20382c75b18947dabf
1 /*
2 * based on linux/arch/arm/mach-pxa/palmld/palmld_ac97.c && linux/arch/arm/mach-pxa/palmld/palmtx_ac97.c
3 * Touchscreen/battery driver for ASUS A730(W). WM9712 AC97 codec.
4 * Author: Serge Nikolaenko <mypal_hh@utl.ru>
5 */
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/init.h>
10 #include <linux/delay.h>
11 #include <linux/interrupt.h>
12 #include <linux/input.h>
13 #include <linux/device.h>
14 #include <linux/workqueue.h>
15 #include <linux/battery.h>
16 #include <linux/irq.h>
18 #include <asm/delay.h>
19 #include <asm/arch/hardware.h>
20 #include <asm/arch/pxa-regs.h>
21 #include <asm/arch/irqs.h>
22 #include <asm/arch/asus730-gpio.h>
24 #include <asm/mach-types.h>
25 #include <asm/mach/arch.h>
26 #include <asm/mach/map.h>
28 #include <sound/driver.h>
29 #include <sound/core.h>
30 #include <sound/pcm.h>
31 #include <sound/initval.h>
32 #include <sound/control.h>
33 #include <sound/ac97_codec.h>
34 #include <sound/wm9712.h>
36 /********************************************************/
38 //static spinlock_t a730_ac97_lock = SPIN_LOCK_UNLOCKED;
40 static struct workqueue_struct *wm9712_phonejack_delayqueue;
41 static struct work_struct wm9712_phonejack_delay_task;
42 static struct workqueue_struct *wm9712_pendown_workqueue;
43 static struct work_struct wm9712_pendown_irq_task;
44 static struct workqueue_struct *wm9712_phonejack_workqueue;
45 static struct work_struct wm9712_phonejack_irq_task;
47 static struct device *a730_ac97_dev = NULL;
48 static struct snd_ac97 *ac97 = NULL;
49 static struct input_dev *a730_ac97_input = NULL;
51 static u64 last_batt_jiff = 0;
52 static int battery_voltage = 0;
53 static int last_voltage = 0;
54 static int cur_voltage = 0;
56 #define PJ_IN 1
57 #define PJ_OUT 0
58 static int a730_phonejack_state = 1;//jack state (0=plugged out; 1=plugged in)
61 static void a730_wm9712_set_routing(struct snd_ac97 *ac97, int allow_phones, int allow_speaker);
63 static DECLARE_MUTEX(digitiser_mutex);
64 static DECLARE_MUTEX_LOCKED(pendown_mutex);
65 static DECLARE_MUTEX_LOCKED(jack_mutex);
66 static DECLARE_MUTEX(battery_update_mutex);
67 static DECLARE_MUTEX(jack_state_switch_sem);
70 * ac97 codec
73 void wm97xx_gpio_func(struct snd_ac97 *ac97, int gpio, int func)
75 int GEn;
76 GEn = snd_ac97_read(ac97, 0x56);
77 if(func) GEn |= gpio;
78 else GEn &= ~gpio;
79 snd_ac97_write(ac97, 0x56, GEn);
82 void wm97xx_gpio_mode(struct snd_ac97 *ac97, int gpio, int config, int polarity, int sticky, int wakeup)
84 int GCn, GPn, GSn, GWn;
85 GCn = snd_ac97_read(ac97, 0x4c);
86 GPn = snd_ac97_read(ac97, 0x4e);
87 GSn = snd_ac97_read(ac97, 0x50);
88 GWn = snd_ac97_read(ac97, 0x52);
90 if (config) GCn |= gpio;
91 else GCn &= ~gpio;
93 if (polarity) GPn |= gpio;
94 else GPn &= ~gpio;
96 if (sticky) GSn |= gpio;
97 else GSn &= ~gpio;
99 if (wakeup) GWn |= gpio;
100 else GWn &= ~gpio;
102 snd_ac97_write(ac97, 0x4c, GCn);
103 snd_ac97_write(ac97, 0x4e, GPn);
104 snd_ac97_write(ac97, 0x50, GSn);
105 snd_ac97_write(ac97, 0x52, GWn);
108 static void wm9712_set_digitiser_power(struct device *dev, int value)
110 u16 d2;
112 d2 = snd_ac97_read(ac97, AC97_WM97XX_DIGITISER2);
113 d2 |= value;
114 snd_ac97_write(ac97, AC97_WM97XX_DIGITISER2, d2);
117 #define AC97_LINK_FRAME 21 /* time in uS for AC97 link frame */
119 static int wm9712_take_reading(int adcsel)
121 int timeout = 15;
122 u16 r76 = 0;
123 u16 r7a;
125 r76 |= adcsel; // set ADCSEL (ADC source)
126 r76 |= WM97XX_DELAY(3); // set settling time delay
127 r76 &= ~(1<<11); // COO = 0 (single measurement)
128 r76 &= ~(1<<10); // CTC = 0 (polling mode)
129 r76 |= (1<<15); // initiate measurement (POLL)
131 snd_ac97_write(ac97, 0x76, r76);
133 // wait settling time
134 udelay ((3 * AC97_LINK_FRAME) + 167);
136 // wait for POLL to go low
137 while((snd_ac97_read(ac97, 0x76) & 0x8000) && timeout)
139 udelay(AC97_LINK_FRAME);
140 timeout--;
143 if (timeout == 0){
144 printk("palmld_ac97: discarding reading due to POLL wait timout on 0x76\n");
145 return 0;
148 r7a = snd_ac97_read(ac97, 0x7a);
150 if ((r7a & WM97XX_ADCSEL_MASK) != adcsel)
152 printk("palmld_ac97: discarding reading -> wrong ADC source\n");
153 return 0;
156 return (int) r7a;
160 * battery
163 void update_data(int force)
165 u16 reading;
167 if(!force && ((last_batt_jiff + HZ * 10) > jiffies)) return;
169 if(down_trylock(&battery_update_mutex) != 0) return;
171 down(&digitiser_mutex);
172 wm9712_set_digitiser_power(a730_ac97_dev, WM97XX_PRP_DET_DIG);
173 reading = wm9712_take_reading(WM9712_ADCSEL_BMON);
174 wm9712_set_digitiser_power(a730_ac97_dev, WM97XX_PRP_DET);
175 up(&digitiser_mutex);
177 last_voltage = cur_voltage;
178 cur_voltage = reading & 0xfff;
179 printk("Battery: %d\n", battery_voltage);
181 last_batt_jiff = jiffies;
183 up(&battery_update_mutex);
186 int get_min_voltage(struct battery *b)
188 return 0;
190 int get_min_charge(struct battery *b)
192 return 0;
194 int get_max_voltage(struct battery *b)
196 return 4750; /* mV */
198 int get_max_charge(struct battery *b)
200 return 1;
202 int get_voltage(struct battery *b)
204 update_data(0);
205 return cur_voltage * 3 * 80586 / 100000;
207 int get_charge(struct battery *b)
209 return 0;
211 int get_status(struct battery *b)
213 return 0; //power_status == POWER_NONE? 0: 1;
216 static struct battery a730_battery = {
217 .name = "a730-ac97",
218 .id = "battery0",
219 .get_min_voltage = get_min_voltage,
220 .get_min_current = NULL,
221 .get_min_charge = get_min_charge,
222 .get_max_voltage = get_max_voltage,
223 .get_max_current = NULL,
224 .get_max_charge = get_max_charge,
225 .get_temp = NULL,
226 .get_voltage = get_voltage,
227 .get_current = NULL,
228 .get_charge = get_charge,
229 .get_status = get_status,
233 static int
234 battery_class_hotplug(struct class_device *dev, char **envp, int num_envp,
235 char *buffer, int buffer_size)
237 return 0;
241 static void battery_class_release(struct class_device *dev)
245 static void battery_class_class_release(struct class *class)
250 * touchscreen
253 static void wm9712_pendown(void)
255 int xread, yread, pressure;
256 int valid_coords = 0, pendown = 0;
258 //pen down brought us here
259 input_report_key(a730_ac97_input, BTN_TOUCH, 1);
260 input_sync(a730_ac97_input);
262 do {
263 xread = wm9712_take_reading(WM97XX_ADCSEL_X);
264 yread = wm9712_take_reading(WM97XX_ADCSEL_Y);
265 pressure = wm9712_take_reading(WM97XX_ADCSEL_PRES);
267 //each value need to have bit 15 to be set - pen is down
268 pendown = ((xread & 0x8000) && (yread & 0x8000) && (pressure & 0x8000));
270 xread &= 0xfff;
271 yread &= 0xfff;
272 pressure &= 0xfff;
274 //not zero
275 valid_coords = xread && yread && pressure;
277 if (pendown && valid_coords && (pressure < 500))
279 input_report_abs(a730_ac97_input, ABS_X, xread);
280 input_report_abs(a730_ac97_input, ABS_Y, yread);
281 input_report_abs(a730_ac97_input, ABS_PRESSURE, pressure);
282 input_sync(a730_ac97_input);
284 else break;
285 set_current_state(TASK_UNINTERRUPTIBLE);
286 schedule_timeout(HZ/100);
287 set_current_state(TASK_RUNNING);
288 } while(pendown && valid_coords);
290 input_report_key(a730_ac97_input, BTN_TOUCH, 0);
291 input_report_abs(a730_ac97_input, ABS_X, 0);
292 input_report_abs(a730_ac97_input, ABS_Y, 0);
293 input_report_abs(a730_ac97_input, ABS_PRESSURE, 0);
294 input_sync(a730_ac97_input);
297 static void wm9712_pendown_handler(void *data)
299 u16 levels, polarity;
301 levels = snd_ac97_read(ac97, AC97_GPIO_STATUS);
302 //polarity = snd_ac97_read(ac97, AC97_GPIO_POLARITY);
304 if (levels & WM97XX_GPIO_13)
306 down(&digitiser_mutex);
307 wm9712_pendown();
308 up(&digitiser_mutex);
309 //polarity &= ~(WM97XX_GPIO_13);
311 //else polarity |= WM97XX_GPIO_13;
313 levels &= ~WM97XX_GPIO_13;
315 //snd_ac97_write(ac97, AC97_GPIO_POLARITY, polarity);
316 //drop GPIO13 bit in any case
317 snd_ac97_write(ac97, AC97_GPIO_STATUS, levels);
318 up(&pendown_mutex);
321 static void wm9712_phonejack_switch_thread(void *data)
323 msleep(100);
324 a730_wm9712_set_routing(ac97, a730_phonejack_state != PJ_OUT, a730_phonejack_state == PJ_OUT);
327 static void wm9712_phonejack_handler(void *data)
329 u16 levels, polarity;
331 levels = snd_ac97_read(ac97, AC97_GPIO_STATUS);
332 polarity = snd_ac97_read(ac97, AC97_GPIO_POLARITY);
334 if (levels & WM97XX_GPIO_1)
336 if (polarity & WM97XX_GPIO_1)
338 a730_phonejack_state = PJ_OUT;//plugged out
339 polarity &= ~WM97XX_GPIO_1;
341 else
343 a730_phonejack_state = PJ_IN;//plugged in
344 polarity |= WM97XX_GPIO_1;
346 if (down_trylock(&jack_state_switch_sem) == 0)
348 queue_work(wm9712_phonejack_delayqueue, &wm9712_phonejack_delay_task);
349 up(&jack_state_switch_sem);
353 levels &= ~WM97XX_GPIO_1;
355 snd_ac97_write(ac97, AC97_GPIO_POLARITY, polarity);
356 snd_ac97_write(ac97, AC97_GPIO_STATUS, levels);
358 up(&jack_mutex);
361 static irqreturn_t wm9712_pendown_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
363 if (!down_trylock(&pendown_mutex)) queue_work(wm9712_pendown_workqueue, &wm9712_pendown_irq_task);
364 return IRQ_HANDLED;
367 static irqreturn_t wm9712_jack_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
369 if (!down_trylock(&jack_mutex)) queue_work(wm9712_phonejack_workqueue, &wm9712_phonejack_irq_task);
370 return IRQ_HANDLED;
373 static int suspended = 0;
375 static int a730_wm9712_setup(void)
377 u16 tmp;
379 /* reset levels */
380 //snd_ac97_write(ac97, AC97_GPIO_STATUS, 0);
382 /* turn off irq gpio inverting, turn on jack insert detect */
383 tmp = snd_ac97_read(ac97, AC97_ADD_FUNC);
384 tmp &= ~1;//no invert irq
385 tmp |= 2;//wake ena
386 tmp &= ~(0x01 << 11);
387 tmp |= (0x01 << 12);//tmp |= (0x01 << 12);
388 snd_ac97_write(ac97, AC97_ADD_FUNC, tmp);
390 /* disable digitiser to save power, enable pen-down detect */
391 tmp = snd_ac97_read(ac97, AC97_WM97XX_DIGITISER2);
392 tmp |= WM97XX_PRP_DET;
393 snd_ac97_write(ac97, AC97_WM97XX_DIGITISER2, tmp);
395 /* enable interrupts on codec's gpio 2 (connected to cpu gpio 27) */
396 wm97xx_gpio_mode(ac97, WM97XX_GPIO_2, WM97XX_GPIO_OUT, WM97XX_GPIO_POL_HIGH, WM97XX_GPIO_NOTSTICKY, WM97XX_GPIO_NOWAKE);
397 wm97xx_gpio_func(ac97, WM97XX_GPIO_2, 0);
399 /* enable interrupts on codec's gpio 3 (connected to cpu gpio 25) */
400 wm97xx_gpio_mode(ac97, WM97XX_GPIO_3, WM97XX_GPIO_OUT, WM97XX_GPIO_POL_HIGH, WM97XX_GPIO_NOTSTICKY, WM97XX_GPIO_NOWAKE);
401 wm97xx_gpio_func(ac97, WM97XX_GPIO_3, 0);
403 wm97xx_gpio_mode(ac97, WM97XX_GPIO_1, WM97XX_GPIO_IN, WM97XX_GPIO_POL_HIGH, WM97XX_GPIO_STICKY, WM97XX_GPIO_WAKE);
404 wm97xx_gpio_func(ac97, WM97XX_GPIO_1, 1);
405 wm97xx_gpio_mode(ac97, WM97XX_GPIO_13, WM97XX_GPIO_OUT, WM97XX_GPIO_POL_HIGH, WM97XX_GPIO_NOTSTICKY, WM97XX_GPIO_NOWAKE);
407 /* turn on the digitiser and pen down detector */
408 tmp = snd_ac97_read(ac97, AC97_WM97XX_DIGITISER2);
409 tmp |= WM97XX_PRP_DETW;// | (0x1 << 9);//plus, WAIT
410 snd_ac97_write(ac97, AC97_WM97XX_DIGITISER2, tmp);
412 up(&jack_mutex);
413 up(&pendown_mutex);
415 snd_ac97_write(ac97, AC97_GPIO_STATUS, 0);
416 snd_ac97_write(ac97, AC97_POWERDOWN, 0);
418 return 0;
421 static int a730_wm9712_suspend(struct device *dev, pm_message_t state)
423 //disable_irq(A730_IRQ(PENDOWN_IRQ));
424 //disable_irq(A730_IRQ(JACK_IRQ));
425 suspended = 1;
426 return 0;
429 static int a730_wm9712_resume(struct device *dev)
431 suspended = 0;
432 a730_wm9712_setup();
433 return 0;
436 //set, where pcm will play to
437 static void a730_wm9712_set_routing(struct snd_ac97 *ac97, int allow_phones, int allow_speaker)
439 int tmp = 0, reg2 = 0, reg4 = 0, reg18 = 0, reg24 = 0, reg26 = 0;
441 if (allow_phones) tmp &= ~(1 << 15);
442 else tmp |= (1 << 15);
443 if (allow_speaker) tmp &= ~(1 << 14);
444 else tmp |= (1 << 14);
446 reg2 = snd_ac97_read(ac97, 0x2);
447 reg4 = snd_ac97_read(ac97, 0x4);
448 reg18 = snd_ac97_read(ac97, 0x18);
449 reg24 = snd_ac97_read(ac97, 0x24);
450 reg26 = snd_ac97_read(ac97, 0x26);
452 if (a730_phonejack_state == PJ_OUT)
454 printk("set_audio_out: p=%d s=%d\n", allow_phones, allow_speaker);
455 reg2 |= (1 << 6);
456 reg18 |= (1 << 13);
457 reg4 |= (1 << 15);
458 reg24 = 0x1F77;//speaker
459 reg26 |= (1 << 8);
460 reg26 &= ~(1 << 9);//DAC on
461 reg26 |= (1 << 14);
463 else
465 printk("set_audio_out: p=%d s=%d\n", allow_phones, allow_speaker);
466 reg2 &= ~(1 << 6);
467 reg18 &= ~(1 << 13);
468 reg4 &= ~(0x01 << 15);
469 reg24 = 0x1CEF;//hphones
470 reg26 |= (1 << 8);
471 reg26 &= ~(1 << 9);
472 reg26 &= ~(1 << 14);
475 snd_ac97_update(ac97, 0x2, reg2);
476 snd_ac97_update(ac97, 0x4, reg4);
477 snd_ac97_update(ac97, 0x18, reg18);
478 snd_ac97_update(ac97, 0x24, reg24);
479 snd_ac97_update(ac97, 0x26, reg26);
481 //unmute dacs
482 //snd_ac97_update_bits(ac97, AC97_PCM, tmp, tmp);
485 static int __init a730_ac97_probe(struct device *dev)
487 int err;
488 int irqflag = IRQF_DISABLED;
489 #ifdef CONFIG_PREEMPT_RT
490 irqflag |= IRQF_NODELAY;
491 #endif
493 ac97 = to_ac97_t(dev);
494 a730_ac97_dev = dev;
496 printk("%s\n", __FUNCTION__);
498 wm9712_pendown_workqueue = create_singlethread_workqueue("pendownd");
499 INIT_WORK(&wm9712_pendown_irq_task, wm9712_pendown_handler, dev);
500 wm9712_phonejack_delayqueue = create_singlethread_workqueue("jackdd");
501 INIT_WORK(&wm9712_phonejack_delay_task, wm9712_phonejack_switch_thread, dev);
502 wm9712_phonejack_workqueue = create_singlethread_workqueue("jackd");
503 INIT_WORK(&wm9712_phonejack_irq_task, wm9712_phonejack_handler, dev);
505 /* setup irq */
506 set_irq_type(A730_IRQ(PENDOWN_IRQ), IRQF_TRIGGER_RISING);
507 err = request_irq(A730_IRQ(PENDOWN_IRQ), wm9712_pendown_irq_handler, irqflag, "WM9712 IRQ2", NULL);
508 if(err) {
509 printk("a730_ac97_probe: cannot request pen down IRQ\n");
510 return -1;
513 set_irq_type(A730_IRQ(JACK_IRQ), IRQF_TRIGGER_RISING);
514 err = request_irq(A730_IRQ(JACK_IRQ), wm9712_jack_irq_handler, irqflag, "WM9712 IRQ3", NULL);
515 if(err) {
516 printk("a730_ac97_probe: cannot request jack detect IRQ\n");
517 return -1;
520 /* setup the input device */
521 a730_ac97_input = input_allocate_device();
523 a730_ac97_input->name = "Asus A730(W) touchscreen";
524 a730_ac97_input->phys = "touchscreen/A730";
525 a730_ac97_input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
526 a730_ac97_input->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
527 input_set_abs_params(a730_ac97_input, ABS_X, 190, 3900, 5, 0);
528 input_set_abs_params(a730_ac97_input, ABS_Y, 190, 3900, 35, 0);
529 input_set_abs_params(a730_ac97_input, ABS_PRESSURE, 0, 150, 5, 0);
530 a730_ac97_input->dev = dev;
531 a730_ac97_input->id.bustype = BUS_HOST;
532 input_register_device(a730_ac97_input);
534 /* register battery */
535 if(battery_class_register(&a730_battery)) {
536 printk(KERN_ERR "a730_ac97_probe: Could not register battery class\n");
537 } else {
538 a730_battery.class_dev.class->release = battery_class_release;
539 // a730_battery.class_dev.class->hotplug = battery_class_hotplug;
540 a730_battery.class_dev.class->class_release = battery_class_class_release;
543 a730_wm9712_setup();
545 return 0;
548 static int a730_ac97_remove (struct device *dev)
550 printk("x: %x\n", snd_ac97_read(ac97, AC97_WM97XX_DIGITISER2));
552 disable_irq(A730_IRQ(PENDOWN_IRQ));
553 disable_irq(A730_IRQ(JACK_IRQ));
555 battery_class_unregister(&a730_battery);
556 input_unregister_device(a730_ac97_input);
558 free_irq(A730_IRQ(PENDOWN_IRQ), NULL);
559 free_irq(A730_IRQ(JACK_IRQ), NULL);
561 enable_irq(A730_IRQ(PENDOWN_IRQ));
562 enable_irq(A730_IRQ(JACK_IRQ));
564 return 0;
567 static struct device_driver a730_ac97_driver = {
568 .name = "WM9712",
569 .bus = &ac97_bus_type,
570 .probe = a730_ac97_probe,
571 .remove = a730_ac97_remove,
572 #ifdef CONFIG_PM
573 .suspend = a730_wm9712_suspend,
574 .resume = a730_wm9712_resume,
575 #endif
578 static int __init a730_ac97_init(void)
580 if(!machine_is_a730()) return -ENODEV;
581 printk("%s\n", __FUNCTION__);
582 return driver_register(&a730_ac97_driver);
585 static void __exit a730_ac97_exit(void)
587 driver_unregister(&a730_ac97_driver);
590 module_init(a730_ac97_init);
591 module_exit(a730_ac97_exit);
593 MODULE_AUTHOR ("Serge Nikolaenko <mypal_hh@utl.ru>");
594 MODULE_DESCRIPTION ("WM9712 AC97 codec support for Asus A730(W)");
595 MODULE_LICENSE ("GPL");