[buildroot] disable sstrip when using musl
[openwrt.git] / 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  */
34 static 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  */
46 struct 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 }