Root/target/linux/ubicom32/files/arch/ubicom32/mach-common/audio.c

1/*
2 * arch/ubicom32/mach-common/audio.c
3 * Generic initialization for Ubicom32 Audio
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
24#include <linux/platform_device.h>
25#include <linux/types.h>
26
27#include <asm/devtree.h>
28#include <asm/audio.h>
29#include <asm/ubi32-pcm.h>
30
31/*
32 * The number of audio devices currently allocated, used for .id
33 */
34static int __initdata audio_device_count;
35
36/*
37 * The maximum number of resources (cards) that the audio will have.
38 * Currently 3, a register space, and up to 2 interrupts.
39 */
40#define AUDIO_MAX_RESOURCES 3
41
42/*
43 * audio_device_alloc
44 * Checks the device tree and allocates a platform_device if found
45 */
46struct platform_device * __init audio_device_alloc(const char *driver_name,
47        const char *node_name, const char *inst_name, int priv_bytes)
48{
49    struct platform_device *pdev;
50    struct resource *res;
51    struct audio_node *audio_node;
52    struct ubi32pcm_platform_data *pdata;
53    struct audio_dev_regs *adr;
54    int idx;
55
56    /*
57     * Check the device tree for the audio node
58     */
59    audio_node = (struct audio_node *)devtree_find_node(node_name);
60    if (!audio_node) {
61        printk(KERN_WARNING "audio device '%s' not found\n", node_name);
62        return NULL;
63    }
64
65    if (audio_node->version != AUDIONODE_VERSION) {
66        printk(KERN_WARNING "audio node not compatible\n");
67        return NULL;
68    }
69
70    /*
71     * Find the instance in this node
72     */
73    adr = audio_node->regs->adr;
74    for (idx = 0; idx < audio_node->regs->max_devs; idx++) {
75        if ((adr->version == AUDIO_DEV_REGS_VERSION) &&
76           (strcmp(adr->name, inst_name) == 0)) {
77            break;
78        }
79        adr++;
80    }
81    if (idx == audio_node->regs->max_devs) {
82        printk(KERN_WARNING "audio inst '%s' not found in device '%s'\n", inst_name, node_name);
83        return NULL;
84    }
85
86    /*
87     * Dynamically create the platform_device structure and resources
88     */
89    pdev = kzalloc(sizeof(struct platform_device) +
90               sizeof(struct ubi32pcm_platform_data) +
91               priv_bytes , GFP_KERNEL);
92    if (!pdev) {
93        printk(KERN_WARNING "audio could not alloc pdev\n");
94        return NULL;
95    }
96
97    res = kzalloc(sizeof(struct resource) * AUDIO_MAX_RESOURCES,
98            GFP_KERNEL);
99    if (!res) {
100        kfree(pdev);
101        printk(KERN_WARNING "audio could not alloc res\n");
102        return NULL;
103    }
104
105    pdev->name = driver_name;
106    pdev->id = audio_device_count++;
107    pdev->resource = res;
108
109    /*
110     * Fill in the resources and platform data from devtree information
111     */
112    res[0].start = (u32_t)(audio_node->regs);
113    res[0].end = (u32_t)(audio_node->regs);
114    res[0].flags = IORESOURCE_MEM;
115    res[1 + AUDIO_TX_IRQ_RESOURCE].start = audio_node->dn.sendirq;
116    res[1 + AUDIO_TX_IRQ_RESOURCE].flags = IORESOURCE_IRQ;
117    res[1 + AUDIO_RX_IRQ_RESOURCE].start = audio_node->dn.recvirq;
118    res[1 + AUDIO_RX_IRQ_RESOURCE].flags = IORESOURCE_IRQ;
119    pdev->num_resources = 3;
120
121    printk(KERN_INFO "Audio.%d '%s':'%s' found irq=%d/%d.%d regs=%p pdev=%p/%p\n",
122        pdev->id, node_name, inst_name, audio_node->dn.sendirq,
123        audio_node->dn.recvirq, idx, audio_node->regs, pdev, res);
124    pdata = (struct ubi32pcm_platform_data *)(pdev + 1);
125    pdev->dev.platform_data = pdata;
126    pdata->node_name = node_name;
127    pdata->inst_name = inst_name;
128    pdata->inst_num = idx;
129    if (priv_bytes) {
130        pdata->priv_data = pdata + 1;
131    }
132
133    return pdev;
134}
135

Archive Download this file



interactive