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>
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;
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
);
73 void wm97xx_gpio_func(struct snd_ac97
*ac97
, int gpio
, int func
)
76 GEn
= snd_ac97_read(ac97
, 0x56);
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
;
93 if (polarity
) GPn
|= gpio
;
96 if (sticky
) GSn
|= gpio
;
99 if (wakeup
) 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
)
112 d2
= snd_ac97_read(ac97
, AC97_WM97XX_DIGITISER2
);
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
)
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
);
144 printk("palmld_ac97: discarding reading due to POLL wait timout on 0x76\n");
148 r7a
= snd_ac97_read(ac97
, 0x7a);
150 if ((r7a
& WM97XX_ADCSEL_MASK
) != adcsel
)
152 printk("palmld_ac97: discarding reading -> wrong ADC source\n");
163 void update_data(int force
)
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
)
190 int get_min_charge(struct battery
*b
)
194 int get_max_voltage(struct battery
*b
)
196 return 4750; /* mV */
198 int get_max_charge(struct battery
*b
)
202 int get_voltage(struct battery
*b
)
205 return cur_voltage
* 3 * 80586 / 100000;
207 int get_charge(struct battery
*b
)
211 int get_status(struct battery
*b
)
213 return 0; //power_status == POWER_NONE? 0: 1;
216 static struct battery a730_battery
= {
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
,
226 .get_voltage
= get_voltage
,
228 .get_charge
= get_charge
,
229 .get_status
= get_status
,
234 battery_class_hotplug(struct class_device *dev, char **envp, int num_envp,
235 char *buffer, int buffer_size)
241 static void battery_class_release(struct class_device
*dev
)
245 static void battery_class_class_release(struct class *class)
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
);
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));
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
);
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
);
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
);
321 static void wm9712_phonejack_switch_thread(void *data
)
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
;
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
);
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
);
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
);
373 static int suspended
= 0;
375 static int a730_wm9712_setup(void)
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
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
);
415 snd_ac97_write(ac97
, AC97_GPIO_STATUS
, 0);
416 snd_ac97_write(ac97
, AC97_POWERDOWN
, 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));
429 static int a730_wm9712_resume(struct device
*dev
)
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
);
458 reg24
= 0x1F77;//speaker
460 reg26
&= ~(1 << 9);//DAC on
465 printk("set_audio_out: p=%d s=%d\n", allow_phones
, allow_speaker
);
468 reg4
&= ~(0x01 << 15);
469 reg24
= 0x1CEF;//hphones
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
);
482 //snd_ac97_update_bits(ac97, AC97_PCM, tmp, tmp);
485 static int __init
a730_ac97_probe(struct device
*dev
)
488 int irqflag
= IRQF_DISABLED
;
489 #ifdef CONFIG_PREEMPT_RT
490 irqflag
|= IRQF_NODELAY
;
493 ac97
= to_ac97_t(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
);
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
);
509 printk("a730_ac97_probe: cannot request pen down IRQ\n");
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
);
516 printk("a730_ac97_probe: cannot request jack detect IRQ\n");
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");
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
;
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
));
567 static struct device_driver a730_ac97_driver
= {
569 .bus
= &ac97_bus_type
,
570 .probe
= a730_ac97_probe
,
571 .remove
= a730_ac97_remove
,
573 .suspend
= a730_wm9712_suspend
,
574 .resume
= a730_wm9712_resume
,
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");