Blame view

drivers/mfd/ucb1400_core.c 3.52 KB
d9105c2b0   Marek Vašut   [ARM] 5184/1: Spl...
1
2
3
4
5
6
7
8
9
10
  /*
   * Core functions for:
   *  Philips UCB1400 multifunction chip
   *
   * Based on ucb1400_ts.c:
   *  Author:	Nicolas Pitre
   *  Created:	September 25, 2006
   *  Copyright:	MontaVista Software, Inc.
   *
   * Spliting done by: Marek Vasut <marek.vasut@gmail.com>
25985edce   Lucas De Marchi   Fix common misspe...
11
   * If something doesn't work and it worked before spliting, e-mail me,
d9105c2b0   Marek Vašut   [ARM] 5184/1: Spl...
12
13
14
15
16
17
18
19
20
21
22
23
   * dont bother Nicolas please ;-)
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   *
   * This code is heavily based on ucb1x00-*.c copyrighted by Russell King
   * covering the UCB1100, UCB1200 and UCB1300..  Support for the UCB1400 has
   * been made separate from ucb1x00-core/ucb1x00-ts on Russell's request.
   */
  
  #include <linux/module.h>
a99bbaf5e   Alexey Dobriyan   headers: remove s...
24
  #include <linux/sched.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
25
  #include <linux/slab.h>
d9105c2b0   Marek Vašut   [ARM] 5184/1: Spl...
26
  #include <linux/ucb1400.h>
cbf806dd9   Sebastian Andrzej Siewior   Input: ucb1400 - ...
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel,
  		int adcsync)
  {
  	unsigned int val;
  
  	if (adcsync)
  		adc_channel |= UCB_ADC_SYNC_ENA;
  
  	ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA | adc_channel);
  	ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA | adc_channel |
  			UCB_ADC_START);
  
  	while (!((val = ucb1400_reg_read(ac97, UCB_ADC_DATA))
  				& UCB_ADC_DAT_VALID))
  		schedule_timeout_uninterruptible(1);
  
  	return val & UCB_ADC_DAT_MASK;
  }
  EXPORT_SYMBOL_GPL(ucb1400_adc_read);
d9105c2b0   Marek Vašut   [ARM] 5184/1: Spl...
46
47
48
49
50
  static int ucb1400_core_probe(struct device *dev)
  {
  	int err;
  	struct ucb1400 *ucb;
  	struct ucb1400_ts ucb_ts;
4cf8e53b3   Marek Vasut   mfd/gpio: add a G...
51
  	struct ucb1400_gpio ucb_gpio;
d9105c2b0   Marek Vašut   [ARM] 5184/1: Spl...
52
  	struct snd_ac97 *ac97;
fb1415975   Marek Vasut   Input: ucb1400_ts...
53
  	struct ucb1400_pdata *pdata = dev->platform_data;
d9105c2b0   Marek Vašut   [ARM] 5184/1: Spl...
54
55
  
  	memset(&ucb_ts, 0, sizeof(ucb_ts));
4cf8e53b3   Marek Vasut   mfd/gpio: add a G...
56
  	memset(&ucb_gpio, 0, sizeof(ucb_gpio));
d9105c2b0   Marek Vašut   [ARM] 5184/1: Spl...
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  
  	ucb = kzalloc(sizeof(struct ucb1400), GFP_KERNEL);
  	if (!ucb) {
  		err = -ENOMEM;
  		goto err;
  	}
  
  	dev_set_drvdata(dev, ucb);
  
  	ac97 = to_ac97_t(dev);
  
  	ucb_ts.id = ucb1400_reg_read(ac97, UCB_ID);
  	if (ucb_ts.id != UCB_ID_1400) {
  		err = -ENODEV;
  		goto err0;
  	}
4cf8e53b3   Marek Vasut   mfd/gpio: add a G...
73
74
75
76
77
78
79
80
81
82
83
84
85
86
  	/* GPIO */
  	ucb_gpio.ac97 = ac97;
  	ucb->ucb1400_gpio = platform_device_alloc("ucb1400_gpio", -1);
  	if (!ucb->ucb1400_gpio) {
  		err = -ENOMEM;
  		goto err0;
  	}
  	err = platform_device_add_data(ucb->ucb1400_gpio, &ucb_gpio,
  					sizeof(ucb_gpio));
  	if (err)
  		goto err1;
  	err = platform_device_add(ucb->ucb1400_gpio);
  	if (err)
  		goto err1;
d9105c2b0   Marek Vašut   [ARM] 5184/1: Spl...
87
88
  	/* TOUCHSCREEN */
  	ucb_ts.ac97 = ac97;
fb1415975   Marek Vasut   Input: ucb1400_ts...
89
90
91
92
93
  
  	if (pdata != NULL && pdata->irq >= 0)
  		ucb_ts.irq = pdata->irq;
  	else
  		ucb_ts.irq = -1;
d9105c2b0   Marek Vašut   [ARM] 5184/1: Spl...
94
95
96
  	ucb->ucb1400_ts = platform_device_alloc("ucb1400_ts", -1);
  	if (!ucb->ucb1400_ts) {
  		err = -ENOMEM;
4cf8e53b3   Marek Vasut   mfd/gpio: add a G...
97
  		goto err2;
d9105c2b0   Marek Vašut   [ARM] 5184/1: Spl...
98
99
100
101
  	}
  	err = platform_device_add_data(ucb->ucb1400_ts, &ucb_ts,
  					sizeof(ucb_ts));
  	if (err)
4cf8e53b3   Marek Vasut   mfd/gpio: add a G...
102
  		goto err3;
d9105c2b0   Marek Vašut   [ARM] 5184/1: Spl...
103
104
  	err = platform_device_add(ucb->ucb1400_ts);
  	if (err)
4cf8e53b3   Marek Vasut   mfd/gpio: add a G...
105
  		goto err3;
d9105c2b0   Marek Vašut   [ARM] 5184/1: Spl...
106
107
  
  	return 0;
4cf8e53b3   Marek Vasut   mfd/gpio: add a G...
108
  err3:
d9105c2b0   Marek Vašut   [ARM] 5184/1: Spl...
109
  	platform_device_put(ucb->ucb1400_ts);
4cf8e53b3   Marek Vasut   mfd/gpio: add a G...
110
  err2:
ef256176c   Axel Lin   mfd: Avoid callin...
111
  	platform_device_del(ucb->ucb1400_gpio);
4cf8e53b3   Marek Vasut   mfd/gpio: add a G...
112
113
  err1:
  	platform_device_put(ucb->ucb1400_gpio);
d9105c2b0   Marek Vašut   [ARM] 5184/1: Spl...
114
115
116
117
118
119
120
121
122
123
124
  err0:
  	kfree(ucb);
  err:
  	return err;
  }
  
  static int ucb1400_core_remove(struct device *dev)
  {
  	struct ucb1400 *ucb = dev_get_drvdata(dev);
  
  	platform_device_unregister(ucb->ucb1400_ts);
4cf8e53b3   Marek Vasut   mfd/gpio: add a G...
125
  	platform_device_unregister(ucb->ucb1400_gpio);
d9105c2b0   Marek Vašut   [ARM] 5184/1: Spl...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
  	kfree(ucb);
  	return 0;
  }
  
  static struct device_driver ucb1400_core_driver = {
  	.name	= "ucb1400_core",
  	.bus	= &ac97_bus_type,
  	.probe	= ucb1400_core_probe,
  	.remove	= ucb1400_core_remove,
  };
  
  static int __init ucb1400_core_init(void)
  {
  	return driver_register(&ucb1400_core_driver);
  }
  
  static void __exit ucb1400_core_exit(void)
  {
  	driver_unregister(&ucb1400_core_driver);
  }
  
  module_init(ucb1400_core_init);
  module_exit(ucb1400_core_exit);
  
  MODULE_DESCRIPTION("Philips UCB1400 driver");
  MODULE_LICENSE("GPL");