wl1273.c 12.5 KB
Newer Older
1 2 3 4 5
/*
 * ALSA SoC WL1273 codec driver
 *
 * Author:      Matti Aaltonen, <matti.j.aaltonen@nokia.com>
 *
6
 * Copyright:   (C) 2010, 2011 Nokia Corporation
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <linux/mfd/wl1273-core.h>
#include <linux/slab.h>
26
#include <linux/module.h>
27 28
#include <sound/pcm.h>
#include <sound/pcm_params.h>
J
Jarkko Nikula 已提交
29
#include <sound/soc.h>
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
#include <sound/initval.h>

#include "wl1273.h"

enum wl1273_mode { WL1273_MODE_BT, WL1273_MODE_FM_RX, WL1273_MODE_FM_TX };

/* codec private data */
struct wl1273_priv {
	enum wl1273_mode mode;
	struct wl1273_core *core;
	unsigned int channels;
};

static int snd_wl1273_fm_set_i2s_mode(struct wl1273_core *core,
				      int rate, int width)
{
46
	struct device *dev = &core->client->dev;
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
	int r = 0;
	u16 mode;

	dev_dbg(dev, "rate: %d\n", rate);
	dev_dbg(dev, "width: %d\n", width);

	mutex_lock(&core->lock);

	mode = core->i2s_mode & ~WL1273_IS2_WIDTH & ~WL1273_IS2_RATE;

	switch (rate) {
	case 48000:
		mode |= WL1273_IS2_RATE_48K;
		break;
	case 44100:
		mode |= WL1273_IS2_RATE_44_1K;
		break;
	case 32000:
		mode |= WL1273_IS2_RATE_32K;
		break;
	case 22050:
		mode |= WL1273_IS2_RATE_22_05K;
		break;
	case 16000:
		mode |= WL1273_IS2_RATE_16K;
		break;
	case 12000:
		mode |= WL1273_IS2_RATE_12K;
		break;
	case 11025:
		mode |= WL1273_IS2_RATE_11_025;
		break;
	case 8000:
		mode |= WL1273_IS2_RATE_8K;
		break;
	default:
		dev_err(dev, "Sampling rate: %d not supported\n", rate);
		r = -EINVAL;
		goto out;
	}

	switch (width) {
	case 16:
		mode |= WL1273_IS2_WIDTH_32;
		break;
	case 20:
		mode |= WL1273_IS2_WIDTH_40;
		break;
	case 24:
		mode |= WL1273_IS2_WIDTH_48;
		break;
	case 25:
		mode |= WL1273_IS2_WIDTH_50;
		break;
	case 30:
		mode |= WL1273_IS2_WIDTH_60;
		break;
	case 32:
		mode |= WL1273_IS2_WIDTH_64;
		break;
	case 40:
		mode |= WL1273_IS2_WIDTH_80;
		break;
	case 48:
		mode |= WL1273_IS2_WIDTH_96;
		break;
	case 64:
		mode |= WL1273_IS2_WIDTH_128;
		break;
	default:
		dev_err(dev, "Data width: %d not supported\n", width);
		r = -EINVAL;
		goto out;
	}

	dev_dbg(dev, "WL1273_I2S_DEF_MODE: 0x%04x\n",  WL1273_I2S_DEF_MODE);
	dev_dbg(dev, "core->i2s_mode: 0x%04x\n", core->i2s_mode);
	dev_dbg(dev, "mode: 0x%04x\n", mode);

	if (core->i2s_mode != mode) {
127
		r = core->write(core, WL1273_I2S_MODE_CONFIG_SET, mode);
128 129 130 131
		if (r)
			goto out;

		core->i2s_mode = mode;
132 133
		r = core->write(core, WL1273_AUDIO_ENABLE,
				WL1273_AUDIO_ENABLE_I2S);
134 135 136 137 138 139 140 141 142 143 144 145
		if (r)
			goto out;
	}
out:
	mutex_unlock(&core->lock);

	return r;
}

static int snd_wl1273_fm_set_channel_number(struct wl1273_core *core,
					    int channel_number)
{
146
	struct device *dev = &core->client->dev;
147 148 149 150 151 152 153 154 155 156
	int r = 0;

	dev_dbg(dev, "%s\n", __func__);

	mutex_lock(&core->lock);

	if (core->channel_number == channel_number)
		goto out;

	if (channel_number == 1 && core->mode == WL1273_MODE_RX)
157
		r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO);
158
	else if (channel_number == 1 && core->mode == WL1273_MODE_TX)
159
		r = core->write(core, WL1273_MONO_SET, WL1273_TX_MONO);
160
	else if (channel_number == 2 && core->mode == WL1273_MODE_RX)
161
		r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO);
162
	else if (channel_number == 2 && core->mode == WL1273_MODE_TX)
163
		r = core->write(core, WL1273_MONO_SET, WL1273_TX_STEREO);
164 165 166 167 168 169 170 171 172 173 174
	else
		r = -EINVAL;
out:
	mutex_unlock(&core->lock);

	return r;
}

static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
175
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
176 177
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);

178
	ucontrol->value.enumerated.item[0] = wl1273->mode;
179 180 181 182

	return 0;
}

183 184 185 186 187 188
/*
 * TODO: Implement the audio routing in the driver. Now this control
 * only indicates the setting that has been done elsewhere (in the user
 * space).
 */
static const char * const wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" };
189 190 191 192

static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol,
				      struct snd_ctl_elem_value *ucontrol)
{
193
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
194 195
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);

196
	if (wl1273->mode == ucontrol->value.enumerated.item[0])
197 198
		return 0;

199
	/* Do not allow changes while stream is running */
200
	if (snd_soc_codec_is_active(codec))
201 202
		return -EPERM;

203
	if (ucontrol->value.enumerated.item[0] >=  ARRAY_SIZE(wl1273_audio_route))
204 205
		return -EINVAL;

206
	wl1273->mode = ucontrol->value.enumerated.item[0];
207 208 209 210

	return 1;
}

211
static SOC_ENUM_SINGLE_EXT_DECL(wl1273_enum, wl1273_audio_route);
212 213 214 215

static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{
216
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
217 218 219 220
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);

	dev_dbg(codec->dev, "%s: enter.\n", __func__);

221
	ucontrol->value.enumerated.item[0] = wl1273->core->audio_mode;
222 223 224 225 226 227 228

	return 0;
}

static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{
229
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
230 231 232 233 234
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
	int val, r = 0;

	dev_dbg(codec->dev, "%s: enter.\n", __func__);

235
	val = ucontrol->value.enumerated.item[0];
236 237 238
	if (wl1273->core->audio_mode == val)
		return 0;

239
	r = wl1273->core->set_audio(wl1273->core, val);
240 241 242 243 244 245
	if (r < 0)
		return r;

	return 1;
}

246
static const char * const wl1273_audio_strings[] = { "Digital", "Analog" };
247

248
static SOC_ENUM_SINGLE_EXT_DECL(wl1273_audio_enum, wl1273_audio_strings);
249 250 251 252

static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *ucontrol)
{
253
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
254 255 256 257 258 259 260 261 262 263 264 265
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);

	dev_dbg(codec->dev, "%s: enter.\n", __func__);

	ucontrol->value.integer.value[0] = wl1273->core->volume;

	return 0;
}

static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *ucontrol)
{
266
	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
267 268 269 270 271
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);
	int r;

	dev_dbg(codec->dev, "%s: enter.\n", __func__);

272 273
	r = wl1273->core->set_volume(wl1273->core,
				     ucontrol->value.integer.value[0]);
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
	if (r)
		return r;

	return 1;
}

static const struct snd_kcontrol_new wl1273_controls[] = {
	SOC_ENUM_EXT("Codec Mode", wl1273_enum,
		     snd_wl1273_get_audio_route, snd_wl1273_set_audio_route),
	SOC_ENUM_EXT("Audio Switch", wl1273_audio_enum,
		     snd_wl1273_fm_audio_get,  snd_wl1273_fm_audio_put),
	SOC_SINGLE_EXT("Volume", 0, 0, WL1273_MAX_VOLUME, 0,
		       snd_wl1273_fm_volume_get, snd_wl1273_fm_volume_put),
};

M
Mark Brown 已提交
289 290 291 292 293 294 295 296 297 298 299 300
static const struct snd_soc_dapm_widget wl1273_dapm_widgets[] = {
	SND_SOC_DAPM_INPUT("RX"),

	SND_SOC_DAPM_OUTPUT("TX"),
};

static const struct snd_soc_dapm_route wl1273_dapm_routes[] = {
	{ "Capture", NULL, "RX" },

	{ "TX", NULL, "Playback" },
};

301 302 303
static int wl1273_startup(struct snd_pcm_substream *substream,
			  struct snd_soc_dai *dai)
{
304
	struct snd_soc_codec *codec = dai->codec;
305 306 307 308
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);

	switch (wl1273->mode) {
	case WL1273_MODE_BT:
309 310 311 312
		snd_pcm_hw_constraint_single(substream->runtime,
					     SNDRV_PCM_HW_PARAM_RATE, 8000);
		snd_pcm_hw_constraint_single(substream->runtime,
					     SNDRV_PCM_HW_PARAM_CHANNELS, 1);
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
		break;
	case WL1273_MODE_FM_RX:
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			pr_err("Cannot play in RX mode.\n");
			return -EINVAL;
		}
		break;
	case WL1273_MODE_FM_TX:
		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
			pr_err("Cannot capture in TX mode.\n");
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
		break;
	}

	return 0;
}

static int wl1273_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params,
			    struct snd_soc_dai *dai)
{
338
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(dai->codec);
339 340 341
	struct wl1273_core *core = wl1273->core;
	unsigned int rate, width, r;

342 343 344
	if (params_width(params) != 16) {
		dev_err(dai->dev, "%d bits/sample not supported\n",
			params_width(params));
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
		return -EINVAL;
	}

	rate = params_rate(params);
	width =  hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min;

	if (wl1273->mode == WL1273_MODE_BT) {
		if (rate != 8000) {
			pr_err("Rate %d not supported.\n", params_rate(params));
			return -EINVAL;
		}

		if (params_channels(params) != 1) {
			pr_err("Only mono supported.\n");
			return -EINVAL;
		}

		return 0;
	}

	if (wl1273->mode == WL1273_MODE_FM_TX &&
	    substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
		pr_err("Only playback supported with TX.\n");
		return -EINVAL;
	}

	if (wl1273->mode == WL1273_MODE_FM_RX  &&
	    substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		pr_err("Only capture supported with RX.\n");
		return -EINVAL;
	}

	if (wl1273->mode != WL1273_MODE_FM_RX  &&
	    wl1273->mode != WL1273_MODE_FM_TX) {
		pr_err("Unexpected mode: %d.\n", wl1273->mode);
		return -EINVAL;
	}

	r = snd_wl1273_fm_set_i2s_mode(core, rate, width);
	if (r)
		return r;

	wl1273->channels = params_channels(params);
	r = snd_wl1273_fm_set_channel_number(core, wl1273->channels);
	if (r)
		return r;

	return 0;
}

395
static const struct snd_soc_dai_ops wl1273_dai_ops = {
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
	.startup	= wl1273_startup,
	.hw_params	= wl1273_hw_params,
};

static struct snd_soc_dai_driver wl1273_dai = {
	.name = "wl1273-fm",
	.playback = {
		.stream_name = "Playback",
		.channels_min = 1,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_8000_48000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE},
	.capture = {
		.stream_name = "Capture",
		.channels_min = 1,
		.channels_max = 2,
		.rates = SNDRV_PCM_RATE_8000_48000,
		.formats = SNDRV_PCM_FMTBIT_S16_LE},
	.ops = &wl1273_dai_ops,
};

/* Audio interface format for the soc_card driver */
int wl1273_get_format(struct snd_soc_codec *codec, unsigned int *fmt)
{
	struct wl1273_priv *wl1273;

	if (codec == NULL || fmt == NULL)
		return -EINVAL;

	wl1273 = snd_soc_codec_get_drvdata(codec);

	switch (wl1273->mode) {
	case WL1273_MODE_FM_RX:
	case WL1273_MODE_FM_TX:
		*fmt =	SND_SOC_DAIFMT_I2S |
			SND_SOC_DAIFMT_NB_NF |
			SND_SOC_DAIFMT_CBM_CFM;

		break;
	case WL1273_MODE_BT:
		*fmt =	SND_SOC_DAIFMT_DSP_A |
			SND_SOC_DAIFMT_IB_NF |
			SND_SOC_DAIFMT_CBM_CFM;

		break;
	default:
		return -EINVAL;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(wl1273_get_format);

static int wl1273_probe(struct snd_soc_codec *codec)
{
451
	struct wl1273_core **core = codec->dev->platform_data;
452 453 454 455 456 457 458 459 460 461
	struct wl1273_priv *wl1273;

	dev_dbg(codec->dev, "%s.\n", __func__);

	if (!core) {
		dev_err(codec->dev, "Platform data is missing.\n");
		return -EINVAL;
	}

	wl1273 = kzalloc(sizeof(struct wl1273_priv), GFP_KERNEL);
462
	if (!wl1273)
463 464 465 466 467 468 469
		return -ENOMEM;

	wl1273->mode = WL1273_MODE_BT;
	wl1273->core = *core;

	snd_soc_codec_set_drvdata(codec, wl1273);

470
	return 0;
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485
}

static int wl1273_remove(struct snd_soc_codec *codec)
{
	struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec);

	dev_dbg(codec->dev, "%s\n", __func__);
	kfree(wl1273);

	return 0;
}

static struct snd_soc_codec_driver soc_codec_dev_wl1273 = {
	.probe = wl1273_probe,
	.remove = wl1273_remove,
M
Mark Brown 已提交
486

487 488
	.controls = wl1273_controls,
	.num_controls = ARRAY_SIZE(wl1273_controls),
M
Mark Brown 已提交
489 490 491 492
	.dapm_widgets = wl1273_dapm_widgets,
	.num_dapm_widgets = ARRAY_SIZE(wl1273_dapm_widgets),
	.dapm_routes = wl1273_dapm_routes,
	.num_dapm_routes = ARRAY_SIZE(wl1273_dapm_routes),
493 494
};

495
static int wl1273_platform_probe(struct platform_device *pdev)
496 497 498 499 500
{
	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wl1273,
				      &wl1273_dai, 1);
}

501
static int wl1273_platform_remove(struct platform_device *pdev)
502 503 504 505 506 507 508 509 510 511 512 513
{
	snd_soc_unregister_codec(&pdev->dev);
	return 0;
}

MODULE_ALIAS("platform:wl1273-codec");

static struct platform_driver wl1273_platform_driver = {
	.driver		= {
		.name	= "wl1273-codec",
	},
	.probe		= wl1273_platform_probe,
514
	.remove		= wl1273_platform_remove,
515 516
};

517
module_platform_driver(wl1273_platform_driver);
518 519 520 521

MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
MODULE_DESCRIPTION("ASoC WL1273 codec driver");
MODULE_LICENSE("GPL");