[go: nahoru, domu]

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>
254e36dd331423fce1f996d93b991453a1a702ca5cPaul Gortmaker#include <linux/module.h>
26383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
27383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen#define DRIVER_DESC "WL1273 FM Radio Core"
28383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
291206552b02f725bdc603e3153b4a32403d7da9e4Axel Linstatic const struct i2c_device_id wl1273_driver_id_table[] = {
30383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	{ WL1273_FM_DRIVER_NAME, 0 },
31383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	{ }
32383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen};
33383268a8e282fb549dabe3a33ccafc9434ab6006Matti AaltonenMODULE_DEVICE_TABLE(i2c, wl1273_driver_id_table);
34383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
3594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonenstatic int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value)
3694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen{
3794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	struct i2c_client *client = core->client;
3894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	u8 b[2];
3994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	int r;
4094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
4194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	r = i2c_smbus_read_i2c_block_data(client, reg, sizeof(b), b);
4294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	if (r != 2) {
4394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		dev_err(&client->dev, "%s: Read: %d fails.\n", __func__, reg);
4494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		return -EREMOTEIO;
4594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	}
4694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
4794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	*value = (u16)b[0] << 8 | b[1];
4894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
4994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	return 0;
5094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen}
5194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
5294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonenstatic int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param)
5394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen{
5494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	struct i2c_client *client = core->client;
5594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	u8 buf[] = { (param >> 8) & 0xff, param & 0xff };
5694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	int r;
5794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
5894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	r = i2c_smbus_write_i2c_block_data(client, cmd, sizeof(buf), buf);
5994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	if (r) {
6094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		dev_err(&client->dev, "%s: Cmd: %d fails.\n", __func__, cmd);
6194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		return r;
6294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	}
6394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
6494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	return 0;
6594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen}
6694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
6794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonenstatic int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 len)
6894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen{
6994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	struct i2c_client *client = core->client;
7094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	struct i2c_msg msg;
7194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	int r;
7294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
7394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	msg.addr = client->addr;
7494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	msg.flags = 0;
7594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	msg.buf = data;
7694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	msg.len = len;
7794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
7894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	r = i2c_transfer(client->adapter, &msg, 1);
7994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	if (r != 1) {
8094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		dev_err(&client->dev, "%s: write error.\n", __func__);
8194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		return -EREMOTEIO;
8294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	}
8394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
8494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	return 0;
8594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen}
8694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
8794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen/**
8894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen * wl1273_fm_set_audio() -	Set audio mode.
8994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen * @core:			A pointer to the device struct.
9094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen * @new_mode:			The new audio mode.
9194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen *
9294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen * Audio modes are WL1273_AUDIO_DIGITAL and WL1273_AUDIO_ANALOG.
9394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen */
9494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonenstatic int wl1273_fm_set_audio(struct wl1273_core *core, unsigned int new_mode)
9594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen{
9694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	int r = 0;
9794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
9894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	if (core->mode == WL1273_MODE_OFF ||
9994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	    core->mode == WL1273_MODE_SUSPENDED)
10094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		return -EPERM;
10194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
10294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	if (core->mode == WL1273_MODE_RX && new_mode == WL1273_AUDIO_DIGITAL) {
10394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		r = wl1273_fm_write_cmd(core, WL1273_PCM_MODE_SET,
10494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen					WL1273_PCM_DEF_MODE);
10594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		if (r)
10694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen			goto out;
10794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
10894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
10994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen					core->i2s_mode);
11094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		if (r)
11194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen			goto out;
11294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
11394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
11494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen					WL1273_AUDIO_ENABLE_I2S);
11594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		if (r)
11694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen			goto out;
11794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
11894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	} else if (core->mode == WL1273_MODE_RX &&
11994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		   new_mode == WL1273_AUDIO_ANALOG) {
12094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
12194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen					WL1273_AUDIO_ENABLE_ANALOG);
12294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		if (r)
12394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen			goto out;
12494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
12594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	} else if (core->mode == WL1273_MODE_TX &&
12694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		   new_mode == WL1273_AUDIO_DIGITAL) {
12794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
12894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen					core->i2s_mode);
12994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		if (r)
13094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen			goto out;
13194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
13294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
13394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen					WL1273_AUDIO_IO_SET_I2S);
13494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		if (r)
13594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen			goto out;
13694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
13794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	} else if (core->mode == WL1273_MODE_TX &&
13894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		   new_mode == WL1273_AUDIO_ANALOG) {
13994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
14094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen					WL1273_AUDIO_IO_SET_ANALOG);
14194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen		if (r)
14294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen			goto out;
14394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	}
14494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
14594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	core->audio_mode = new_mode;
14694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonenout:
14794fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	return r;
14894fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen}
14994fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
15094fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen/**
15194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen * wl1273_fm_set_volume() -	Set volume.
15294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen * @core:			A pointer to the device struct.
15394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen * @volume:			The new volume value.
15494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen */
15594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonenstatic int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
15694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen{
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	dev_dbg(&client->dev, "%s\n", __func__);
176383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
177383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	mfd_remove_devices(&client->dev);
178383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
179383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	return 0;
180383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen}
181383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
182f791be492f76dea7b0641ed227a60eeb2fa7e255Bill Pembertonstatic int wl1273_core_probe(struct i2c_client *client,
183383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen				       const struct i2c_device_id *id)
184383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen{
185334a41ce9b753ec615e8c6c50ee07d6197190610Jingoo Han	struct wl1273_fm_platform_data *pdata = dev_get_platdata(&client->dev);
186383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	struct wl1273_core *core;
187383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	struct mfd_cell *cell;
188383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	int children = 0;
189383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	int r = 0;
190383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
191383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	dev_dbg(&client->dev, "%s\n", __func__);
192383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
193383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	if (!pdata) {
194383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		dev_err(&client->dev, "No platform data.\n");
195383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		return -EINVAL;
196383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	}
197383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
198383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	if (!(pdata->children & WL1273_RADIO_CHILD)) {
199383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		dev_err(&client->dev, "Cannot function without radio child.\n");
200383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		return -EINVAL;
201383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	}
202383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
203bba078273e259c7eff729ac00a1476987ad5413aJingoo Han	core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL);
204383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	if (!core)
205383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		return -ENOMEM;
206383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
207383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	core->pdata = pdata;
208383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	core->client = client;
209383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	mutex_init(&core->lock);
210383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
211383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	i2c_set_clientdata(client, core);
212383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
213383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	dev_dbg(&client->dev, "%s: Have V4L2.\n", __func__);
214383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
215383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	cell = &core->cells[children];
216383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	cell->name = "wl1273_fm_radio";
2179e554696c03e04c51d095c1c451e26a8cb6a84faSamuel Ortiz	cell->platform_data = &core;
2189e554696c03e04c51d095c1c451e26a8cb6a84faSamuel Ortiz	cell->pdata_size = sizeof(core);
219383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	children++;
220383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
22194fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	core->read = wl1273_fm_read_reg;
22294fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	core->write = wl1273_fm_write_cmd;
22394fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	core->write_data = wl1273_fm_write_data;
22494fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	core->set_audio = wl1273_fm_set_audio;
22594fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen	core->set_volume = wl1273_fm_set_volume;
22694fd5b7401e330498331ea3667d796e74c63d08aMatti Aaltonen
227383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	if (pdata->children & WL1273_CODEC_CHILD) {
228383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		cell = &core->cells[children];
229383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
230383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		dev_dbg(&client->dev, "%s: Have codec.\n", __func__);
231383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		cell->name = "wl1273-codec";
2329e554696c03e04c51d095c1c451e26a8cb6a84faSamuel Ortiz		cell->platform_data = &core;
2339e554696c03e04c51d095c1c451e26a8cb6a84faSamuel Ortiz		cell->pdata_size = sizeof(core);
234383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		children++;
235383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	}
236383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
237383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	dev_dbg(&client->dev, "%s: number of children: %d.\n",
238383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		__func__, children);
239383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
240383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	r = mfd_add_devices(&client->dev, -1, core->cells,
2410848c94fb4a5cc213a7fb0fb3a5721ad6e16f096Mark Brown			    children, NULL, 0, NULL);
242383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	if (r)
243383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		goto err;
244383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
245383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	return 0;
246383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
247383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonenerr:
248383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	pdata->free_resources();
249383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
250383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	dev_dbg(&client->dev, "%s\n", __func__);
251383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
252383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	return r;
253383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen}
254383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
255383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonenstatic struct i2c_driver wl1273_core_driver = {
256383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	.driver = {
257383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		.name = WL1273_FM_DRIVER_NAME,
258383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	},
259383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	.probe = wl1273_core_probe,
260383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	.id_table = wl1273_driver_id_table,
26184449216b01f9c2b4c9b1882f9d6abba07b7b7caBill Pemberton	.remove = wl1273_core_remove,
262383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen};
263383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
264383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonenstatic int __init wl1273_core_init(void)
265383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen{
266383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	int r;
267383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
268383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	r = i2c_add_driver(&wl1273_core_driver);
269383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	if (r) {
270383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		pr_err(WL1273_FM_DRIVER_NAME
271383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		       ": driver registration failed\n");
272383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen		return r;
273383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	}
274383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
275383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	return r;
276383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen}
277383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
278383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonenstatic void __exit wl1273_core_exit(void)
279383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen{
280383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen	i2c_del_driver(&wl1273_core_driver);
281383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen}
282383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonenlate_initcall(wl1273_core_init);
283383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonenmodule_exit(wl1273_core_exit);
284383268a8e282fb549dabe3a33ccafc9434ab6006Matti Aaltonen
285383268a8e282fb549dabe3a33ccafc9434ab6006Matti AaltonenMODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
286383268a8e282fb549dabe3a33ccafc9434ab6006Matti AaltonenMODULE_DESCRIPTION(DRIVER_DESC);
287383268a8e282fb549dabe3a33ccafc9434ab6006Matti AaltonenMODULE_LICENSE("GPL");
288