[go: nahoru, domu]

wl1273-core.c revision 94fd5b7401e330498331ea3667d796e74c63d08a
1383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen/*
2383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen * MFD driver for wl1273 FM radio and audio codec submodules.
3383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen *
494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen * Copyright (C) 2011 Nokia Corporation
5383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen * Author: Matti Aaltonen <matti.j.aaltonen@nokia.com>
6383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen *
7383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen * This program is free software; you can redistribute it and/or modify
8383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen * it under the terms of the GNU General Public License version 2 as
9383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen * published by the Free Software Foundation.
10383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen *
11383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen * This program is distributed in the hope that it will be useful, but
12383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen * WITHOUT ANY WARRANTY; without even the implied warranty of
13383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen * General Public License for more details.
15383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen *
16383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen * You should have received a copy of the GNU General Public License
17383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen * along with this program; if not, write to the Free Software
18383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen * 02110-1301 USA
20383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen *
21383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen */
22383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
23383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen#include <linux/mfd/wl1273-core.h>
24383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen#include <linux/slab.h>
25383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
26383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen#define DRIVER_DESC "WL1273 FM Radio Core"
27383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
28383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonenstatic struct i2c_device_id wl1273_driver_id_table[] = {
29383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	{ WL1273_FM_DRIVER_NAME, 0 },
30383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	{ }
31383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen};
32383268a8e282fb549dabe3a33ccafc9434ab6006Matti AaltonenMODULE_DEVICE_TABLE(i2c, wl1273_driver_id_table);
33383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
3494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonenstatic int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value)
3594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen{
3694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	struct i2c_client *client = core->client;
3794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	u8 b[2];
3894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	int r;
3994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
4094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	r = i2c_smbus_read_i2c_block_data(client, reg, sizeof(b), b);
4194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	if (r != 2) {
4294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		dev_err(&client->dev, "%s: Read: %d fails.\n", __func__, reg);
4394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		return -EREMOTEIO;
4494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	}
4594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
4694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	*value = (u16)b[0] << 8 | b[1];
4794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
4894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	return 0;
4994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen}
5094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
5194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonenstatic int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param)
5294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen{
5394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	struct i2c_client *client = core->client;
5494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	u8 buf[] = { (param >> 8) & 0xff, param & 0xff };
5594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	int r;
5694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
5794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	r = i2c_smbus_write_i2c_block_data(client, cmd, sizeof(buf), buf);
5894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	if (r) {
5994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		dev_err(&client->dev, "%s: Cmd: %d fails.\n", __func__, cmd);
6094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		return r;
6194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	}
6294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
6394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	return 0;
6494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen}
6594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
6694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonenstatic int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 len)
6794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen{
6894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	struct i2c_client *client = core->client;
6994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	struct i2c_msg msg;
7094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	int r;
7194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
7294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	msg.addr = client->addr;
7394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	msg.flags = 0;
7494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	msg.buf = data;
7594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	msg.len = len;
7694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
7794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	r = i2c_transfer(client->adapter, &msg, 1);
7894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	if (r != 1) {
7994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		dev_err(&client->dev, "%s: write error.\n", __func__);
8094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		return -EREMOTEIO;
8194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	}
8294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
8394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	return 0;
8494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen}
8594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
8694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen/**
8794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen * wl1273_fm_set_audio() -	Set audio mode.
8894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen * @core:			A pointer to the device struct.
8994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen * @new_mode:			The new audio mode.
9094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen *
9194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen * Audio modes are WL1273_AUDIO_DIGITAL and WL1273_AUDIO_ANALOG.
9294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen */
9394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonenstatic int wl1273_fm_set_audio(struct wl1273_core *core, unsigned int new_mode)
9494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen{
9594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	int r = 0;
9694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
9794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	if (core->mode == WL1273_MODE_OFF ||
9894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	    core->mode == WL1273_MODE_SUSPENDED)
9994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		return -EPERM;
10094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
10194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	if (core->mode == WL1273_MODE_RX && new_mode == WL1273_AUDIO_DIGITAL) {
10294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		r = wl1273_fm_write_cmd(core, WL1273_PCM_MODE_SET,
10394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen					WL1273_PCM_DEF_MODE);
10494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		if (r)
10594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen			goto out;
10694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
10794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
10894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen					core->i2s_mode);
10994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		if (r)
11094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen			goto out;
11194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
11294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
11394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen					WL1273_AUDIO_ENABLE_I2S);
11494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		if (r)
11594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen			goto out;
11694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
11794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	} else if (core->mode == WL1273_MODE_RX &&
11894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		   new_mode == WL1273_AUDIO_ANALOG) {
11994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
12094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen					WL1273_AUDIO_ENABLE_ANALOG);
12194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		if (r)
12294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen			goto out;
12394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
12494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	} else if (core->mode == WL1273_MODE_TX &&
12594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		   new_mode == WL1273_AUDIO_DIGITAL) {
12694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
12794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen					core->i2s_mode);
12894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		if (r)
12994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen			goto out;
13094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
13194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
13294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen					WL1273_AUDIO_IO_SET_I2S);
13394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		if (r)
13494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen			goto out;
13594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
13694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	} else if (core->mode == WL1273_MODE_TX &&
13794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		   new_mode == WL1273_AUDIO_ANALOG) {
13894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
13994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen					WL1273_AUDIO_IO_SET_ANALOG);
14094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		if (r)
14194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen			goto out;
14294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	}
14394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
14494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	core->audio_mode = new_mode;
14594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonenout:
14694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	return r;
14794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen}
14894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
14994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen/**
15094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen * wl1273_fm_set_volume() -	Set volume.
15194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen * @core:			A pointer to the device struct.
15294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen * @volume:			The new volume value.
15394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen */
15494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonenstatic int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
15594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen{
15694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	u16 val;
15794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	int r;
15894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
15994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	if (volume > WL1273_MAX_VOLUME)
16094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		return -EINVAL;
16194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
16294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	if (core->volume == volume)
16394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		return 0;
16494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
16594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	r = wl1273_fm_write_cmd(core, WL1273_VOLUME_SET, volume);
16694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	if (r)
16794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		return r;
16894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
16994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	core->volume = volume;
17094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	return 0;
17194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen}
17294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
173383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonenstatic int wl1273_core_remove(struct i2c_client *client)
174383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen{
175383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	struct wl1273_core *core = i2c_get_clientdata(client);
176383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
177383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	dev_dbg(&client->dev, "%s\n", __func__);
178383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
179383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	mfd_remove_devices(&client->dev);
180383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	kfree(core);
181383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
182383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	return 0;
183383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen}
184383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
185383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonenstatic int __devinit wl1273_core_probe(struct i2c_client *client,
186383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen				       const struct i2c_device_id *id)
187383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen{
188383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	struct wl1273_fm_platform_data *pdata = client->dev.platform_data;
189383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	struct wl1273_core *core;
190383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	struct mfd_cell *cell;
191383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	int children = 0;
192383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	int r = 0;
193383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
194383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	dev_dbg(&client->dev, "%s\n", __func__);
195383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
196383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	if (!pdata) {
197383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		dev_err(&client->dev, "No platform data.\n");
198383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		return -EINVAL;
199383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	}
200383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
201383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	if (!(pdata->children & WL1273_RADIO_CHILD)) {
202383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		dev_err(&client->dev, "Cannot function without radio child.\n");
203383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		return -EINVAL;
204383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	}
205383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
206383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	core = kzalloc(sizeof(*core), GFP_KERNEL);
207383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	if (!core)
208383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		return -ENOMEM;
209383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
210383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	core->pdata = pdata;
211383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	core->client = client;
212383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	mutex_init(&core->lock);
213383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
214383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	i2c_set_clientdata(client, core);
215383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
216383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	dev_dbg(&client->dev, "%s: Have V4L2.\n", __func__);
217383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
218383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	cell = &core->cells[children];
219383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	cell->name = "wl1273_fm_radio";
220383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	cell->platform_data = &core;
221383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	cell->data_size = sizeof(core);
222383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	children++;
223383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
22494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	core->read = wl1273_fm_read_reg;
22594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	core->write = wl1273_fm_write_cmd;
22694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	core->write_data = wl1273_fm_write_data;
22794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	core->set_audio = wl1273_fm_set_audio;
22894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	core->set_volume = wl1273_fm_set_volume;
22994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
230383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	if (pdata->children & WL1273_CODEC_CHILD) {
231383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		cell = &core->cells[children];
232383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
233383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		dev_dbg(&client->dev, "%s: Have codec.\n", __func__);
234383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		cell->name = "wl1273-codec";
235383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		cell->platform_data = &core;
236383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		cell->data_size = sizeof(core);
237383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		children++;
238383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	}
239383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
240383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	dev_dbg(&client->dev, "%s: number of children: %d.\n",
241383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		__func__, children);
242383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
243383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	r = mfd_add_devices(&client->dev, -1, core->cells,
244383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen			    children, NULL, 0);
245383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	if (r)
246383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		goto err;
247383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
248383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	return 0;
249383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
250383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonenerr:
251383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	pdata->free_resources();
252383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	kfree(core);
253383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
254383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	dev_dbg(&client->dev, "%s\n", __func__);
255383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
256383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	return r;
257383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen}
258383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
259383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonenstatic struct i2c_driver wl1273_core_driver = {
260383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	.driver = {
261383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		.name = WL1273_FM_DRIVER_NAME,
262383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	},
263383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	.probe = wl1273_core_probe,
264383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	.id_table = wl1273_driver_id_table,
265383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	.remove = __devexit_p(wl1273_core_remove),
266383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen};
267383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
268383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonenstatic int __init wl1273_core_init(void)
269383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen{
270383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	int r;
271383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
272383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	r = i2c_add_driver(&wl1273_core_driver);
273383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	if (r) {
274383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		pr_err(WL1273_FM_DRIVER_NAME
275383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		       ": driver registration failed\n");
276383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		return r;
277383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	}
278383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
279383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	return r;
280383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen}
281383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
282383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonenstatic void __exit wl1273_core_exit(void)
283383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen{
284383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	i2c_del_driver(&wl1273_core_driver);
285383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen}
286383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonenlate_initcall(wl1273_core_init);
287383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonenmodule_exit(wl1273_core_exit);
288383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
289383268a8e282fb549dabe3a33ccafc9434ab6006Matti AaltonenMODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
290383268a8e282fb549dabe3a33ccafc9434ab6006Matti AaltonenMODULE_DESCRIPTION(DRIVER_DESC);
291383268a8e282fb549dabe3a33ccafc9434ab6006Matti AaltonenMODULE_LICENSE("GPL");
292