Root/target/linux/ubicom32/files/arch/ubicom32/mach-ip7k/board-ip7500iap.c

1/*
2 * arch/ubicom32/mach-ip7k/board-ip7500iap.c
3 * Support for IP7500 Internet Audio Player
4 *
5 * This file supports the IP7500 Internet Audio Player:
6 * 8007-1110 Rev 1.0
7 *
8 * (C) Copyright 2009, Ubicom, Inc.
9 *
10 * This file is part of the Ubicom32 Linux Kernel Port.
11 *
12 * The Ubicom32 Linux Kernel Port is free software: you can redistribute
13 * it and/or modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, either version 2 of the
15 * License, or (at your option) any later version.
16 *
17 * The Ubicom32 Linux Kernel Port is distributed in the hope that it
18 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
19 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
20 * the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with the Ubicom32 Linux Kernel Port. If not,
24 * see <http://www.gnu.org/licenses/>.
25 */
26#include <linux/device.h>
27#include <linux/gpio.h>
28#include <asm/board.h>
29
30#include <linux/delay.h>
31
32#include <linux/platform_device.h>
33#include <asm/audio.h>
34#include <linux/i2c.h>
35#include <linux/i2c-gpio.h>
36
37#include <asm/ubicom32sd.h>
38#include <asm/sd_tio.h>
39
40#include <asm/ubicom32bl.h>
41
42#include <asm/machdep.h>
43
44/******************************************************************************
45 * SD/IO Port F (Slot 1) platform data
46 */
47static struct resource ip7500iap_portf_sd_resources[] = {
48    /*
49     * Send IRQ
50     */
51    [0] = {
52        /*
53         * The init routine will query the devtree and fill this in
54         */
55        .flags = IORESOURCE_IRQ,
56    },
57
58    /*
59     * Receive IRQ
60     */
61    [1] = {
62        /*
63         * The init routine will query the devtree and fill this in
64         */
65        .flags = IORESOURCE_IRQ,
66    },
67
68    /*
69     * Memory Mapped Registers
70     */
71    [2] = {
72        /*
73         * The init routine will query the devtree and fill this in
74         */
75        .flags = IORESOURCE_MEM,
76    },
77};
78
79static struct ubicom32sd_card ip7500iap_portf_sd_cards[] = {
80    [0] = {
81        .pin_wp = GPIO_RF_7,
82        .wp_polarity = 1,
83        .pin_pwr = GPIO_RF_8,
84        .pin_cd = GPIO_RF_6,
85    },
86};
87
88static struct ubicom32sd_platform_data ip7500iap_portf_sd_platform_data = {
89    .ncards = 1,
90    .cards = ip7500iap_portf_sd_cards,
91};
92
93static struct platform_device ip7500iap_portf_sd_device = {
94    .name = "ubicom32sd",
95    .id = 0,
96    .resource = ip7500iap_portf_sd_resources,
97    .num_resources = ARRAY_SIZE(ip7500iap_portf_sd_resources),
98    .dev = {
99            .platform_data = &ip7500iap_portf_sd_platform_data,
100    },
101
102};
103
104/*
105 * ip7500iap_portf_sd_init
106 */
107static void ip7500iap_portf_sd_init(void)
108{
109    /*
110     * Check the device tree for the sd_tio
111     */
112    struct sd_tio_node *sd_node = (struct sd_tio_node *)devtree_find_node("portf_sd");
113    if (!sd_node) {
114        printk(KERN_INFO "PortF SDTIO not found\n");
115        return;
116    }
117
118    /*
119     * Fill in the resources and platform data from devtree information
120     */
121    ip7500iap_portf_sd_resources[0].start = sd_node->dn.sendirq;
122    ip7500iap_portf_sd_resources[1].start = sd_node->dn.recvirq;
123    ip7500iap_portf_sd_resources[2].start = (u32_t)&(sd_node->regs);
124    ip7500iap_portf_sd_resources[2].end = (u32_t)&(sd_node->regs) + sizeof(sd_node->regs);
125
126    platform_device_register(&ip7500iap_portf_sd_device);
127}
128
129/******************************************************************************
130 * SD/IO Port B (Slot 2) platform data
131 */
132static struct resource ip7500iap_portb_sd_resources[] = {
133    /*
134     * Send IRQ
135     */
136    [0] = {
137        /*
138         * The init routine will query the devtree and fill this in
139         */
140        .flags = IORESOURCE_IRQ,
141    },
142
143    /*
144     * Receive IRQ
145     */
146    [1] = {
147        /*
148         * The init routine will query the devtree and fill this in
149         */
150        .flags = IORESOURCE_IRQ,
151    },
152
153    /*
154     * Memory Mapped Registers
155     */
156    [2] = {
157        /*
158         * The init routine will query the devtree and fill this in
159         */
160        .flags = IORESOURCE_MEM,
161    },
162};
163
164static struct ubicom32sd_card ip7500iap_portb_sd_cards[] = {
165    [0] = {
166        .pin_wp = GPIO_RB_13,
167        .wp_polarity = 1,
168        .pin_pwr = GPIO_RB_11,
169        .pin_cd = GPIO_RB_12,
170    },
171};
172
173static struct ubicom32sd_platform_data ip7500iap_portb_sd_platform_data = {
174    .ncards = 1,
175    .cards = ip7500iap_portb_sd_cards,
176};
177
178static struct platform_device ip7500iap_portb_sd_device = {
179    .name = "ubicom32sd",
180    .id = 1,
181    .resource = ip7500iap_portb_sd_resources,
182    .num_resources = ARRAY_SIZE(ip7500iap_portb_sd_resources),
183    .dev = {
184            .platform_data = &ip7500iap_portb_sd_platform_data,
185    },
186
187};
188
189/*
190 * ip7500iap_portb_sd_init
191 */
192static void ip7500iap_portb_sd_init(void)
193{
194    /*
195     * Check the device tree for the sd_tio
196     */
197    struct sd_tio_node *sd_node = (struct sd_tio_node *)devtree_find_node("portb_sd");
198    if (!sd_node) {
199        printk(KERN_INFO "PortB SDTIO not found\n");
200        return;
201    }
202
203    /*
204     * Fill in the resources and platform data from devtree information
205     */
206    ip7500iap_portb_sd_resources[0].start = sd_node->dn.sendirq;
207    ip7500iap_portb_sd_resources[1].start = sd_node->dn.recvirq;
208    ip7500iap_portb_sd_resources[2].start = (u32_t)&(sd_node->regs);
209    ip7500iap_portb_sd_resources[2].end = (u32_t)&(sd_node->regs) + sizeof(sd_node->regs);
210
211    platform_device_register(&ip7500iap_portb_sd_device);
212}
213
214/******************************************************************************
215 * Touch controller
216 *
217 * Connected via I2C bus, interrupt on PA6
218 */
219#include <linux/i2c/tsc2007.h>
220
221/*
222 * ip7500iap_tsc2007_exit_platform_hw
223 */
224static void ip7500iap_tsc2007_exit_platform_hw(void)
225{
226    UBICOM32_IO_PORT(RA)->ctl0 &= ~(0x03 << 19);
227    gpio_free(GPIO_RA_6);
228}
229
230/*
231 * ip7500iap_tsc2007_init_platform_hw
232 */
233static int ip7500iap_tsc2007_init_platform_hw(void)
234{
235    int res = gpio_request(GPIO_RA_6, "TSC2007_IRQ");
236    if (res) {
237        return res;
238    }
239
240    UBICOM32_IO_PORT(RA)->ctl0 &= ~(0x03 << 19);
241    UBICOM32_IO_PORT(RA)->ctl0 |= (0x02 << 19);
242    return 0;
243}
244
245/*
246 * ip7500iap_tsc2007_get_pendown_state
247 */
248static int ip7500iap_tsc2007_get_pendown_state(void)
249{
250    return !gpio_get_value(GPIO_RA_6);
251}
252
253static struct tsc2007_platform_data ip7500iap_tsc2007_data = {
254    .model = 2007,
255    .x_plate_ohms = 350,
256    .get_pendown_state = ip7500iap_tsc2007_get_pendown_state,
257    .init_platform_hw = ip7500iap_tsc2007_init_platform_hw,
258    .exit_platform_hw = ip7500iap_tsc2007_exit_platform_hw,
259};
260
261/******************************************************************************
262 * i2c devices
263 *
264 * DO NOT CHANGE THE ORDER HERE unless you know how this works. There
265 * are hardcoded indicies which refer to the order of drivers listed here.
266 */
267static struct i2c_board_info __initdata ip7500iap_i2c_board_info[] = {
268    /*
269     * U6, CS4350 DAC, address 0x4B
270     */
271    {
272        .type = "cs4350",
273        .addr = 0x4B,
274    },
275
276    /*
277     * U20, S35390A RTC, address 0x30
278     */
279    {
280        .type = "s35390a",
281        .addr = 0x30,
282    },
283
284    /*
285     * U9, TSC2007 Touch screen controller, address 0x49, irq RA6
286     */
287    {
288        .type = "tsc2007",
289        .addr = 0x49,
290        .irq = 46,
291        .platform_data = &ip7500iap_tsc2007_data,
292    },
293};
294
295/*
296 * I2C bus on the board, SDA PE4, SCL PE5
297 */
298static struct i2c_gpio_platform_data ip7500iap_i2c_data = {
299    .sda_pin = GPIO_RF_14,
300    .scl_pin = GPIO_RF_13,
301    .sda_is_open_drain = 0,
302    .scl_is_open_drain = 0,
303    .udelay = 50,
304};
305
306static struct platform_device ip7500iap_i2c_device = {
307    .name = "i2c-gpio",
308    .id = 0,
309    .dev = {
310        .platform_data = &ip7500iap_i2c_data,
311    },
312};
313
314/******************************************************************************
315 * Backlight on the board PD0, hardware PWM
316 */
317static struct ubicom32bl_platform_data ip7500iap_backlight_data = {
318    .type = UBICOM32BL_TYPE_PWM,
319    .pwm_channel = 2,
320    .pwm_prescale = 15,
321    .pwm_period = 60,
322    .default_intensity = 0x80,
323};
324
325static struct platform_device ip7500iap_backlight_device = {
326    .name = "ubicom32bl",
327    .id = -1,
328    .dev = {
329        .platform_data = &ip7500iap_backlight_data,
330    },
331};
332
333/******************************************************************************
334 * Devices on this board
335 */
336static struct platform_device *ip7500iap_devices[] __initdata = {
337    &ip7500iap_i2c_device,
338    &ip7500iap_backlight_device,
339};
340
341/*
342 * ip7500iap_power_off
343 * Called to turn the power off for this board
344 */
345static void ip7500iap_power_off(void)
346{
347    gpio_set_value(GPIO_RF_11, 0);
348}
349
350/*
351 * ip7500iap_init
352 * Called to add the devices which we have on this board
353 */
354static int __init ip7500iap_init(void)
355{
356    struct platform_device *audio_dev;
357    struct platform_device *audio_dev2;
358    int ret;
359
360    board_init();
361
362    ubi_gpio_init();
363
364    /*
365     * Hold the POWER_HOLD line
366     */
367    ret = gpio_request(GPIO_RF_11, "POWER_HOLD");
368    if (ret) {
369        printk(KERN_ERR "%s: could not request POWER_HOLD GPIO\n", __FUNCTION__);
370    }
371    gpio_direction_output(GPIO_RF_11, 1);
372    mach_power_off = ip7500iap_power_off;
373
374    /*
375     * DAC nRESET line
376     */
377    ret = gpio_request(GPIO_RE_7, "DAC_nRESET");
378    if (ret) {
379        printk(KERN_ERR "%s: could not request DAC_nRESET GPIO\n", __FUNCTION__);
380    }
381    gpio_direction_output(GPIO_RE_7, 0);
382    udelay(1);
383    gpio_set_value(GPIO_RE_7, 1);
384
385    /*
386     * Bring up any SDIO slots
387     */
388    ip7500iap_portb_sd_init();
389    ip7500iap_portf_sd_init();
390
391    /*
392     * Bring up audio devices
393     */
394    platform_add_devices(ip7500iap_devices, ARRAY_SIZE(ip7500iap_devices));
395
396    audio_dev = audio_device_alloc("snd-ubi32-cs4350", "audio", "audio-i2sout", 0);
397    if (audio_dev) {
398        ip7500iap_i2c_board_info[0].platform_data = audio_dev;
399    }
400
401    audio_dev2 = audio_device_alloc("snd-ubi32-generic", "audio", "audio-spdifout", 0);
402    if (audio_dev2) {
403        platform_device_register(audio_dev2);
404    }
405
406    printk(KERN_INFO "%s: registering i2c resources\n", __FUNCTION__);
407    i2c_register_board_info(0, ip7500iap_i2c_board_info, ARRAY_SIZE(ip7500iap_i2c_board_info));
408
409    printk(KERN_INFO "IP7500 Internet Audio Player\n");
410
411    return 0;
412}
413
414arch_initcall(ip7500iap_init);
415

Archive Download this file



interactive