blob: 529d65ba5353bd58de151ffe876355ad900c62ba [file] [log] [blame]
Matti Aaltonen383268a2010-12-10 11:41:33 -03001/*
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
28static struct i2c_device_id wl1273_driver_id_table[] = {
29 { WL1273_FM_DRIVER_NAME, 0 },
30 { }
31};
32MODULE_DEVICE_TABLE(i2c, wl1273_driver_id_table);
33
34static 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);
Matti Aaltonen383268a2010-12-10 11:41:33 -030041 kfree(core);
42
43 return 0;
44}
45
46static int __devinit wl1273_core_probe(struct i2c_client *client,
47 const struct i2c_device_id *id)
48{
49 struct wl1273_fm_platform_data *pdata = client->dev.platform_data;
50 struct wl1273_core *core;
51 struct mfd_cell *cell;
52 int children = 0;
53 int r = 0;
54
55 dev_dbg(&client->dev, "%s\n", __func__);
56
57 if (!pdata) {
58 dev_err(&client->dev, "No platform data.\n");
59 return -EINVAL;
60 }
61
62 if (!(pdata->children & WL1273_RADIO_CHILD)) {
63 dev_err(&client->dev, "Cannot function without radio child.\n");
64 return -EINVAL;
65 }
66
67 core = kzalloc(sizeof(*core), GFP_KERNEL);
68 if (!core)
69 return -ENOMEM;
70
71 core->pdata = pdata;
72 core->client = client;
73 mutex_init(&core->lock);
74
75 i2c_set_clientdata(client, core);
76
77 dev_dbg(&client->dev, "%s: Have V4L2.\n", __func__);
78
79 cell = &core->cells[children];
80 cell->name = "wl1273_fm_radio";
Andres Salomon65e52352011-02-17 19:07:25 -080081 cell->mfd_data = &core;
Matti Aaltonen383268a2010-12-10 11:41:33 -030082 children++;
83
84 if (pdata->children & WL1273_CODEC_CHILD) {
85 cell = &core->cells[children];
86
87 dev_dbg(&client->dev, "%s: Have codec.\n", __func__);
88 cell->name = "wl1273-codec";
Andres Salomon65e52352011-02-17 19:07:25 -080089 cell->mfd_data = &core;
Matti Aaltonen383268a2010-12-10 11:41:33 -030090 children++;
91 }
92
93 dev_dbg(&client->dev, "%s: number of children: %d.\n",
94 __func__, children);
95
96 r = mfd_add_devices(&client->dev, -1, core->cells,
97 children, NULL, 0);
98 if (r)
99 goto err;
100
101 return 0;
102
103err:
Matti Aaltonen383268a2010-12-10 11:41:33 -0300104 pdata->free_resources();
105 kfree(core);
106
107 dev_dbg(&client->dev, "%s\n", __func__);
108
109 return r;
110}
111
112static struct i2c_driver wl1273_core_driver = {
113 .driver = {
114 .name = WL1273_FM_DRIVER_NAME,
115 },
116 .probe = wl1273_core_probe,
117 .id_table = wl1273_driver_id_table,
118 .remove = __devexit_p(wl1273_core_remove),
119};
120
121static int __init wl1273_core_init(void)
122{
123 int r;
124
125 r = i2c_add_driver(&wl1273_core_driver);
126 if (r) {
127 pr_err(WL1273_FM_DRIVER_NAME
128 ": driver registration failed\n");
129 return r;
130 }
131
132 return r;
133}
134
135static void __exit wl1273_core_exit(void)
136{
137 i2c_del_driver(&wl1273_core_driver);
138}
139late_initcall(wl1273_core_init);
140module_exit(wl1273_core_exit);
141
142MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
143MODULE_DESCRIPTION(DRIVER_DESC);
144MODULE_LICENSE("GPL");