move new files out from platform support patch
[openwrt/openwrt.git] / target / linux / ubicom32 / files / arch / ubicom32 / mach-ip7k / board-ip7160dpf.c
1 /*
2 * arch/ubicom32/mach-ip7k/board-ip7160dpf.c
3 * Platform initialization for ip7160dpf board.
4 *
5 * (C) Copyright 2009, Ubicom, Inc.
6 *
7 * This file is part of the Ubicom32 Linux Kernel Port.
8 *
9 * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10 * it and/or modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation, either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with the Ubicom32 Linux Kernel Port. If not,
21 * see <http://www.gnu.org/licenses/>.
22 *
23 * Ubicom32 implementation derived from (with many thanks):
24 * arch/m68knommu
25 * arch/blackfin
26 * arch/parisc
27 */
28 #include <linux/device.h>
29 #include <linux/platform_device.h>
30 #include <linux/delay.h>
31 #include <linux/gpio.h>
32
33 #include <linux/i2c.h>
34 #include <linux/i2c-gpio.h>
35
36 #include <linux/input.h>
37
38 #include <asm/board.h>
39 #include <asm/machdep.h>
40 #include <asm/ubicom32hid.h>
41 #include <asm/vdc_tio.h>
42 #include <asm/audio.h>
43
44 /*
45 * Backlight on the board PD0, hardware PWM
46 */
47 static const struct ubicom32hid_button ip7160dpf_ubicom32hid_buttons[] = {
48 {
49 .type = EV_KEY,
50 .code = KEY_UP,
51 .bit = 0,
52 },
53 {
54 .type = EV_KEY,
55 .code = KEY_LEFT,
56 .bit = 1,
57 },
58 {
59 .type = EV_KEY,
60 .code = KEY_RIGHT,
61 .bit = 2,
62 },
63 {
64 .type = EV_KEY,
65 .code = KEY_DOWN,
66 .bit = 3,
67 },
68 {
69 .type = EV_KEY,
70 .code = KEY_ENTER,
71 .bit = 4,
72 },
73 {
74 .type = EV_KEY,
75 .code = KEY_MENU,
76 .bit = 5,
77 },
78 {
79 .type = EV_KEY,
80 .code = KEY_ESC,
81 .bit = 7,
82 },
83 };
84
85 static const struct ubicom32hid_ir ip7160dpf_ubicom32hid_ircodes[] = {
86 {
87 .type = EV_KEY,
88 .code = KEY_UP,
89 .ir_code = 0xF807916E
90 },
91 {
92 .type = EV_KEY,
93 .code = KEY_DOWN,
94 .ir_code = 0xF20D916E
95 },
96 {
97 .type = EV_KEY,
98 .code = KEY_LEFT,
99 .ir_code = 0xF609916E
100 },
101 {
102 .type = EV_KEY,
103 .code = KEY_RIGHT,
104 .ir_code = 0xF40B916E
105 },
106 {
107 .type = EV_KEY,
108 .code = KEY_ENTER,
109 .ir_code = 0xF50A916E
110 },
111 { /* rotate */
112 .type = EV_KEY,
113 .code = KEY_FN_F1,
114 .ir_code = 0xF906916E
115 },
116 {
117 .type = EV_KEY,
118 .code = KEY_MENU,
119 .ir_code = 0xF708916E
120 },
121 { /* font size */
122 .type = EV_KEY,
123 .code = KEY_FN_F2,
124 .ir_code = 0xF30C916E
125 },
126 {
127 .type = EV_KEY,
128 .code = KEY_ESC,
129 .ir_code = 0xF10E916E
130 },
131 {
132 .type = EV_KEY,
133 .code = KEY_VOLUMEUP,
134 .ir_code = 0xF00F916E
135 },
136 {
137 .type = EV_KEY,
138 .code = KEY_VOLUMEDOWN,
139 .ir_code = 0xED12916E
140 },
141 {
142 .type = EV_KEY,
143 .code = KEY_MUTE,
144 .ir_code = 0xEA15916E
145 },
146 {
147 .type = EV_KEY,
148 .code = KEY_INFO,
149 .ir_code = 0xEF10916E
150 },
151 { /* Like */
152 .type = EV_KEY,
153 .code = KEY_FN_F3,
154 .ir_code = 0xEE11916E
155 },
156 { /* Dislike */
157 .type = EV_KEY,
158 .code = KEY_FN_F4,
159 .ir_code = 0xEB14916E
160 },
161 {
162 .type = EV_KEY,
163 .code = KEY_POWER,
164 .ir_code = 0xFD02916E
165 },
166 };
167
168 static struct ubicom32hid_platform_data ip7160dpf_ubicom32hid_platform_data = {
169 .gpio_reset = GPIO_RI_5,
170 .gpio_reset_polarity = 0,
171 .type = UBICOM32HID_BL_TYPE_PWM,
172 .invert = 0,
173 .default_intensity = 128,
174 .buttons = ip7160dpf_ubicom32hid_buttons,
175 .nbuttons = ARRAY_SIZE(ip7160dpf_ubicom32hid_buttons),
176 .ircodes = ip7160dpf_ubicom32hid_ircodes,
177 .nircodes = ARRAY_SIZE(ip7160dpf_ubicom32hid_ircodes),
178 };
179
180 /*
181 * Devices on the I2C bus
182 * This board has a "bus 2" which is isolated from the main bus by U47
183 * and pin RI0. It should be safe to always enable bus 2 by setting
184 * RI0 to low, however, it should be noted that on all existing configurations
185 * of this board, U49 and U51 are not populated.
186 */
187 static struct i2c_board_info __initdata ip7160dpf_i2c_board_info[] = {
188 /*
189 * U37, CS4350 DAC, address 0x4B, bus 2
190 * THIS ENTRY MUST BE FIRST
191 */
192 {
193 .type = "cs4350",
194 .addr = 0x4B,
195 }
196
197 /*
198 * U24, ubicom32hid
199 */
200 {
201 .type = "ubicom32hid",
202 .addr = 0x08,
203 .platform_data = &ip7160dpf_ubicom32hid_platform_data,
204 },
205
206 /*
207 * U49, ISL29001 Ambient Light Sensor, address 0x44, bus 2 (may not be stuffed)
208 */
209
210 /*
211 * U51, S35390A RTC, address 0x30, bus 2 (may not be stuffed)
212 */
213 #ifdef CONFIG_RTC_DRV_S35390A
214 {
215 .type = "s35390a",
216 .addr = 0x30,
217 },
218 #endif
219 };
220
221 /*
222 * I2C bus on the board, SDA PI1, SCL PI2
223 */
224 static struct i2c_gpio_platform_data ip7160dpf_i2c_data = {
225 .sda_pin = GPIO_RI_1,
226 .scl_pin = GPIO_RI_2,
227 .sda_is_open_drain = 0,
228 .scl_is_open_drain = 0,
229 .scl_is_output_only = 1,
230 .udelay = 6,
231 };
232
233 static struct platform_device ip7160dpf_i2c_device = {
234 .name = "i2c-gpio",
235 .id = 0,
236 .dev = {
237 .platform_data = &ip7160dpf_i2c_data,
238 },
239 };
240
241 /*
242 * List of all devices in our system
243 */
244 static struct platform_device *ip7160dpf_devices[] __initdata = {
245 &ip7160dpf_i2c_device,
246 };
247
248 /*
249 * ip7160dpf_power_off
250 * Called to turn the power off for this board
251 */
252 static void ip7160dpf_power_off(void)
253 {
254 gpio_set_value(GPIO_RF_14, 0);
255 }
256
257 /*
258 * ip7160dpf_init
259 * Called to add the devices which we have on this board
260 */
261 static int __init ip7160dpf_init(void)
262 {
263 int ret;
264 struct platform_device *audio_dev;
265
266 ubi_gpio_init();
267
268 /*
269 * Hold the POWER_HOLD line
270 */
271 ret = gpio_request(GPIO_RF_14, "POWER_HOLD");
272 if (ret) {
273 printk(KERN_ERR "%s: could not request POWER_HOLD GPIO\n", __FUNCTION__);
274 }
275 gpio_direction_output(GPIO_RF_14, 1);
276 mach_power_off = ip7160dpf_power_off;
277
278 /*
279 * USB SEL_HOST_USB line
280 */
281 ret = gpio_request(GPIO_RI_13, "SEL_HOST_USB");
282 if (ret) {
283 printk(KERN_ERR "%s: could not request SEL_HOST_USB GPIO\n", __FUNCTION__);
284 }
285 gpio_direction_output(GPIO_RI_13, 0);
286
287 /*
288 * USB/DAC nRESET line
289 */
290 ret = gpio_request(GPIO_RI_3, "USB_DAC_nRESET");
291 if (ret) {
292 printk(KERN_ERR "%s: could not request USB_DAC_nRESET GPIO\n", __FUNCTION__);
293 }
294 gpio_direction_output(GPIO_RI_3, 0);
295 udelay(1);
296 gpio_direction_output(GPIO_RI_3, 1);
297
298 /*
299 * I2C BUS2 Disable line
300 */
301 ret = gpio_request(GPIO_RI_0, "DISABLE_BUS2");
302 if (ret) {
303 printk(KERN_ERR "%s: could not request DISABLE_BUS2 GPIO\n", __FUNCTION__);
304 }
305 gpio_direction_output(GPIO_RI_0, 0);
306
307 vdc_tio_init();
308
309 printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__);
310 platform_add_devices(ip7160dpf_devices, ARRAY_SIZE(ip7160dpf_devices));
311
312 /*
313 * Allocate the audio driver if we can
314 */
315 audio_dev = audio_device_alloc("snd-ubi32-cs4350", "audio-i2sout", 0);
316 if (audio_dev) {
317 ip7160dpf_i2c_board_info[0].platform_data = audio_dev;
318 }
319
320 printk(KERN_INFO "%s: registering i2c resources\n", __FUNCTION__);
321 i2c_register_board_info(0, ip7160dpf_i2c_board_info, ARRAY_SIZE(ip7160dpf_i2c_board_info));
322
323 return 0;
324 }
325
326 arch_initcall(ip7160dpf_init);