]>
Commit | Line | Data |
---|---|---|
383268a8 MA |
1 | /* |
2 | * MFD driver for wl1273 FM radio and audio codec submodules. | |
3 | * | |
4 | * Copyright (C) 2010 Nokia Corporation | |
5 | * Author: Matti Aaltonen <matti.j.aaltonen@nokia.com> | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License version 2 as | |
9 | * published by the Free Software Foundation. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, but | |
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | |
19 | * 02110-1301 USA | |
20 | * | |
21 | */ | |
22 | ||
23 | #include <linux/mfd/wl1273-core.h> | |
24 | #include <linux/slab.h> | |
25 | ||
26 | #define DRIVER_DESC "WL1273 FM Radio Core" | |
27 | ||
28 | static struct i2c_device_id wl1273_driver_id_table[] = { | |
29 | { WL1273_FM_DRIVER_NAME, 0 }, | |
30 | { } | |
31 | }; | |
32 | MODULE_DEVICE_TABLE(i2c, wl1273_driver_id_table); | |
33 | ||
34 | static int wl1273_core_remove(struct i2c_client *client) | |
35 | { | |
36 | struct wl1273_core *core = i2c_get_clientdata(client); | |
37 | ||
38 | dev_dbg(&client->dev, "%s\n", __func__); | |
39 | ||
40 | mfd_remove_devices(&client->dev); | |
41 | i2c_set_clientdata(client, NULL); | |
42 | kfree(core); | |
43 | ||
44 | return 0; | |
45 | } | |
46 | ||
47 | static int __devinit wl1273_core_probe(struct i2c_client *client, | |
48 | const struct i2c_device_id *id) | |
49 | { | |
50 | struct wl1273_fm_platform_data *pdata = client->dev.platform_data; | |
51 | struct wl1273_core *core; | |
52 | struct mfd_cell *cell; | |
53 | int children = 0; | |
54 | int r = 0; | |
55 | ||
56 | dev_dbg(&client->dev, "%s\n", __func__); | |
57 | ||
58 | if (!pdata) { | |
59 | dev_err(&client->dev, "No platform data.\n"); | |
60 | return -EINVAL; | |
61 | } | |
62 | ||
63 | if (!(pdata->children & WL1273_RADIO_CHILD)) { | |
64 | dev_err(&client->dev, "Cannot function without radio child.\n"); | |
65 | return -EINVAL; | |
66 | } | |
67 | ||
68 | core = kzalloc(sizeof(*core), GFP_KERNEL); | |
69 | if (!core) | |
70 | return -ENOMEM; | |
71 | ||
72 | core->pdata = pdata; | |
73 | core->client = client; | |
74 | mutex_init(&core->lock); | |
75 | ||
76 | i2c_set_clientdata(client, core); | |
77 | ||
78 | dev_dbg(&client->dev, "%s: Have V4L2.\n", __func__); | |
79 | ||
80 | cell = &core->cells[children]; | |
81 | cell->name = "wl1273_fm_radio"; | |
82 | cell->platform_data = &core; | |
83 | cell->data_size = sizeof(core); | |
84 | children++; | |
85 | ||
86 | if (pdata->children & WL1273_CODEC_CHILD) { | |
87 | cell = &core->cells[children]; | |
88 | ||
89 | dev_dbg(&client->dev, "%s: Have codec.\n", __func__); | |
90 | cell->name = "wl1273-codec"; | |
91 | cell->platform_data = &core; | |
92 | cell->data_size = sizeof(core); | |
93 | children++; | |
94 | } | |
95 | ||
96 | dev_dbg(&client->dev, "%s: number of children: %d.\n", | |
97 | __func__, children); | |
98 | ||
99 | r = mfd_add_devices(&client->dev, -1, core->cells, | |
100 | children, NULL, 0); | |
101 | if (r) | |
102 | goto err; | |
103 | ||
104 | return 0; | |
105 | ||
106 | err: | |
107 | i2c_set_clientdata(client, NULL); | |
108 | pdata->free_resources(); | |
109 | kfree(core); | |
110 | ||
111 | dev_dbg(&client->dev, "%s\n", __func__); | |
112 | ||
113 | return r; | |
114 | } | |
115 | ||
116 | static struct i2c_driver wl1273_core_driver = { | |
117 | .driver = { | |
118 | .name = WL1273_FM_DRIVER_NAME, | |
119 | }, | |
120 | .probe = wl1273_core_probe, | |
121 | .id_table = wl1273_driver_id_table, | |
122 | .remove = __devexit_p(wl1273_core_remove), | |
123 | }; | |
124 | ||
125 | static int __init wl1273_core_init(void) | |
126 | { | |
127 | int r; | |
128 | ||
129 | r = i2c_add_driver(&wl1273_core_driver); | |
130 | if (r) { | |
131 | pr_err(WL1273_FM_DRIVER_NAME | |
132 | ": driver registration failed\n"); | |
133 | return r; | |
134 | } | |
135 | ||
136 | return r; | |
137 | } | |
138 | ||
139 | static void __exit wl1273_core_exit(void) | |
140 | { | |
141 | i2c_del_driver(&wl1273_core_driver); | |
142 | } | |
143 | late_initcall(wl1273_core_init); | |
144 | module_exit(wl1273_core_exit); | |
145 | ||
146 | MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>"); | |
147 | MODULE_DESCRIPTION(DRIVER_DESC); | |
148 | MODULE_LICENSE("GPL"); |