File Index
Files and directories
Sign in
FILE

pcm6240.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/codecs/pcm6240.c C
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// ALSA SoC Texas Instruments PCM6240 Family Audio ADC/DAC Device
   4//
   5// Copyright (C) 2022 - 2024 Texas Instruments Incorporated
   6// https://www.ti.com
   7//
   8// The PCM6240 driver implements a flexible and configurable
   9// algo coefficient setting for one, two, or even multiple
  10// PCM6240 Family chips.
  11//
  12// Author: Shenghao Ding <shenghao-ding@ti.com>
  13//
  14
  15#include <linux/unaligned.h>
  16#include <linux/firmware.h>
  17#include <linux/gpio/consumer.h>
  18#include <linux/i2c.h>
  19#include <linux/module.h>
  20#include <linux/of_irq.h>
  21#include <linux/of_address.h>
  22#include <linux/regmap.h>
  23#include <sound/pcm_params.h>
  24#include <sound/soc.h>
  25#include <sound/tlv.h>
  26
  27#include "pcm6240.h"
  28
  29static const struct i2c_device_id pcmdevice_i2c_id[] = {
  30	{ "adc3120",  ADC3120  },
  31	{ "adc5120",  ADC5120  },
  32	{ "adc6120",  ADC6120  },
  33	{ "dix4192",  DIX4192  },
  34	{ "pcm1690",  PCM1690  },
  35	{ "pcm3120",  PCM3120  },
  36	{ "pcm3140",  PCM3140  },
  37	{ "pcm5120",  PCM5120  },
  38	{ "pcm5140",  PCM5140  },
  39	{ "pcm6120",  PCM6120  },
  40	{ "pcm6140",  PCM6140  },
  41	{ "pcm6240",  PCM6240  },
  42	{ "pcm6260",  PCM6260  },
  43	{ "pcm9211",  PCM9211  },
  44	{ "pcmd3140", PCMD3140 },
  45	{ "pcmd3180", PCMD3180 },
  46	{ "pcmd512x", PCMD512X },
  47	{ "taa5212",  TAA5212  },
  48	{ "taa5412",  TAA5412  },
  49	{ "tad5212",  TAD5212  },
  50	{ "tad5412",  TAD5412  },
  51	{}
  52};
  53MODULE_DEVICE_TABLE(i2c, pcmdevice_i2c_id);
  54
  55static const char *const pcmdev_ctrl_name[] = {
  56	"%s i2c%d Dev%d Ch%d Ana Volume",
  57	"%s i2c%d Dev%d Ch%d Digi Volume",
  58	"%s i2c%d Dev%d Ch%d Fine Volume",
  59};
  60
  61static const struct pcmdevice_mixer_control adc5120_analog_gain_ctl[] = {
  62	{
  63		.shift = 1,
  64		.reg = ADC5120_REG_CH1_ANALOG_GAIN,
  65		.max = 0x54,
  66		.invert = 0,
  67	},
  68	{
  69		.shift = 1,
  70		.reg = ADC5120_REG_CH2_ANALOG_GAIN,
  71		.max = 0x54,
  72		.invert = 0,
  73	}
  74};
  75
  76static const struct pcmdevice_mixer_control adc5120_digi_gain_ctl[] = {
  77	{
  78		.shift = 0,
  79		.reg = ADC5120_REG_CH1_DIGITAL_GAIN,
  80		.max = 0xff,
  81		.invert = 0,
  82	},
  83	{
  84		.shift = 0,
  85		.reg = ADC5120_REG_CH2_DIGITAL_GAIN,
  86		.max = 0xff,
  87		.invert = 0,
  88	}
  89};
  90
  91static const struct pcmdevice_mixer_control pcm1690_digi_gain_ctl[] = {
  92	{
  93		.shift = 0,
  94		.reg = PCM1690_REG_CH1_DIGITAL_GAIN,
  95		.max = 0xff,
  96		.invert = 0,
  97	},
  98	{
  99		.shift = 0,
 100		.reg = PCM1690_REG_CH2_DIGITAL_GAIN,
 101		.max = 0xff,
 102		.invert = 0,
 103	},
 104	{
 105		.shift = 0,
 106		.reg = PCM1690_REG_CH3_DIGITAL_GAIN,
 107		.max = 0xff,
 108		.invert = 0,
 109	},
 110	{
 111		.shift = 0,
 112		.reg = PCM1690_REG_CH4_DIGITAL_GAIN,
 113		.max = 0xff,
 114		.invert = 0,
 115	},
 116	{
 117		.shift = 0,
 118		.reg = PCM1690_REG_CH5_DIGITAL_GAIN,
 119		.max = 0xff,
 120		.invert = 0,
 121	},
 122	{
 123		.shift = 0,
 124		.reg = PCM1690_REG_CH6_DIGITAL_GAIN,
 125		.max = 0xff,
 126		.invert = 0,
 127	},
 128	{
 129		.shift = 0,
 130		.reg = PCM1690_REG_CH7_DIGITAL_GAIN,
 131		.max = 0xff,
 132		.invert = 0,
 133	},
 134	{
 135		.shift = 0,
 136		.reg = PCM1690_REG_CH8_DIGITAL_GAIN,
 137		.max = 0xff,
 138		.invert = 0,
 139	}
 140};
 141
 142static const struct pcmdevice_mixer_control pcm6240_analog_gain_ctl[] = {
 143	{
 144		.shift = 2,
 145		.reg = PCM6240_REG_CH1_ANALOG_GAIN,
 146		.max = 0x42,
 147		.invert = 0,
 148	},
 149	{
 150		.shift = 2,
 151		.reg = PCM6240_REG_CH2_ANALOG_GAIN,
 152		.max = 0x42,
 153		.invert = 0,
 154	},
 155	{
 156		.shift = 2,
 157		.reg = PCM6240_REG_CH3_ANALOG_GAIN,
 158		.max = 0x42,
 159		.invert = 0,
 160	},
 161	{
 162		.shift = 2,
 163		.reg = PCM6240_REG_CH4_ANALOG_GAIN,
 164		.max = 0x42,
 165		.invert = 0,
 166	}
 167};
 168
 169static const struct pcmdevice_mixer_control pcm6240_digi_gain_ctl[] = {
 170	{
 171		.shift = 0,
 172		.reg = PCM6240_REG_CH1_DIGITAL_GAIN,
 173		.max = 0xff,
 174		.invert = 0,
 175	},
 176	{
 177		.shift = 0,
 178		.reg = PCM6240_REG_CH2_DIGITAL_GAIN,
 179		.max = 0xff,
 180		.invert = 0,
 181	},
 182	{
 183		.shift = 0,
 184		.reg = PCM6240_REG_CH3_DIGITAL_GAIN,
 185		.max = 0xff,
 186		.invert = 0,
 187	},
 188	{
 189		.shift = 0,
 190		.reg = PCM6240_REG_CH4_DIGITAL_GAIN,
 191		.max = 0xff,
 192		.invert = 0,
 193	}
 194};
 195
 196static const struct pcmdevice_mixer_control pcm6260_analog_gain_ctl[] = {
 197	{
 198		.shift = 2,
 199		.reg = PCM6260_REG_CH1_ANALOG_GAIN,
 200		.max = 0x42,
 201		.invert = 0,
 202	},
 203	{
 204		.shift = 2,
 205		.reg = PCM6260_REG_CH2_ANALOG_GAIN,
 206		.max = 0x42,
 207		.invert = 0,
 208	},
 209	{
 210		.shift = 2,
 211		.reg = PCM6260_REG_CH3_ANALOG_GAIN,
 212		.max = 0x42,
 213		.invert = 0,
 214	},
 215	{
 216		.shift = 2,
 217		.reg = PCM6260_REG_CH4_ANALOG_GAIN,
 218		.max = 0x42,
 219		.invert = 0,
 220	},
 221	{
 222		.shift = 2,
 223		.reg = PCM6260_REG_CH5_ANALOG_GAIN,
 224		.max = 0x42,
 225		.invert = 0,
 226	},
 227	{
 228		.shift = 2,
 229		.reg = PCM6260_REG_CH6_ANALOG_GAIN,
 230		.max = 0x42,
 231		.invert = 0,
 232	}
 233};
 234
 235static const struct pcmdevice_mixer_control pcm6260_digi_gain_ctl[] = {
 236	{
 237		.shift = 0,
 238		.reg = PCM6260_REG_CH1_DIGITAL_GAIN,
 239		.max = 0xff,
 240		.invert = 0,
 241	},
 242	{
 243		.shift = 0,
 244		.reg = PCM6260_REG_CH2_DIGITAL_GAIN,
 245		.max = 0xff,
 246		.invert = 0,
 247	},
 248	{
 249		.shift = 0,
 250		.reg = PCM6260_REG_CH3_DIGITAL_GAIN,
 251		.max = 0xff,
 252		.invert = 0,
 253	},
 254	{
 255		.shift = 0,
 256		.reg = PCM6260_REG_CH4_DIGITAL_GAIN,
 257		.max = 0xff,
 258		.invert = 0,
 259	},
 260	{
 261		.shift = 0,
 262		.reg = PCM6260_REG_CH5_DIGITAL_GAIN,
 263		.max = 0xff,
 264		.invert = 0,
 265	},
 266	{
 267		.shift = 0,
 268		.reg = PCM6260_REG_CH6_DIGITAL_GAIN,
 269		.max = 0xff,
 270		.invert = 0,
 271	}
 272};
 273
 274static const struct pcmdevice_mixer_control pcm9211_digi_gain_ctl[] = {
 275	{
 276		.shift = 0,
 277		.reg = PCM9211_REG_CH1_DIGITAL_GAIN,
 278		.max = 0xff,
 279		.invert = 0,
 280	},
 281	{
 282		.shift = 0,
 283		.reg = PCM9211_REG_CH2_DIGITAL_GAIN,
 284		.max = 0xff,
 285		.invert = 0,
 286	}
 287};
 288
 289static const struct pcmdevice_mixer_control pcmd3140_digi_gain_ctl[] = {
 290	{
 291		.shift = 0,
 292		.reg = PCMD3140_REG_CH1_DIGITAL_GAIN,
 293		.max = 0xff,
 294		.invert = 0,
 295	},
 296	{
 297		.shift = 0,
 298		.reg = PCMD3140_REG_CH2_DIGITAL_GAIN,
 299		.max = 0xff,
 300		.invert = 0,
 301	},
 302	{
 303		.shift = 0,
 304		.reg = PCMD3140_REG_CH3_DIGITAL_GAIN,
 305		.max = 0xff,
 306		.invert = 0,
 307	},
 308	{
 309		.shift = 0,
 310		.reg = PCMD3140_REG_CH4_DIGITAL_GAIN,
 311		.max = 0xff,
 312		.invert = 0,
 313	}
 314};
 315
 316static const struct pcmdevice_mixer_control pcmd3140_fine_gain_ctl[] = {
 317	{
 318		.shift = 4,
 319		.reg = PCMD3140_REG_CH1_FINE_GAIN,
 320		.max = 0xf,
 321		.invert = 0,
 322	},
 323	{
 324		.shift = 4,
 325		.reg = PCMD3140_REG_CH2_FINE_GAIN,
 326		.max = 0xf,
 327		.invert = 0,
 328	},
 329	{
 330		.shift = 4,
 331		.reg = PCMD3140_REG_CH3_FINE_GAIN,
 332		.max = 0xf,
 333		.invert = 0,
 334	},
 335	{
 336		.shift = 4,
 337		.reg = PCMD3140_REG_CH4_FINE_GAIN,
 338		.max = 0xf,
 339		.invert = 0,
 340	}
 341};
 342
 343static const struct pcmdevice_mixer_control pcmd3180_digi_gain_ctl[] = {
 344	{
 345		.shift = 0,
 346		.reg = PCMD3180_REG_CH1_DIGITAL_GAIN,
 347		.max = 0xff,
 348		.invert = 0,
 349	},
 350	{
 351		.shift = 0,
 352		.reg = PCMD3180_REG_CH2_DIGITAL_GAIN,
 353		.max = 0xff,
 354		.invert = 0,
 355	},
 356	{
 357		.shift = 0,
 358		.reg = PCMD3180_REG_CH3_DIGITAL_GAIN,
 359		.max = 0xff,
 360		.invert = 0,
 361	},
 362	{
 363		.shift = 0,
 364		.reg = PCMD3180_REG_CH4_DIGITAL_GAIN,
 365		.max = 0xff,
 366		.invert = 0,
 367	},
 368	{
 369		.shift = 0,
 370		.reg = PCMD3180_REG_CH5_DIGITAL_GAIN,
 371		.max = 0xff,
 372		.invert = 0,
 373	},
 374	{
 375		.shift = 0,
 376		.reg = PCMD3180_REG_CH6_DIGITAL_GAIN,
 377		.max = 0xff,
 378		.invert = 0,
 379	},
 380	{
 381		.shift = 0,
 382		.reg = PCMD3180_REG_CH7_DIGITAL_GAIN,
 383		.max = 0xff,
 384		.invert = 0,
 385	},
 386	{
 387		.shift = 0,
 388		.reg = PCMD3180_REG_CH8_DIGITAL_GAIN,
 389		.max = 0xff,
 390		.invert = 0,
 391	}
 392};
 393
 394static const struct pcmdevice_mixer_control pcmd3180_fine_gain_ctl[] = {
 395	{
 396		.shift = 4,
 397		.reg = PCMD3180_REG_CH1_FINE_GAIN,
 398		.max = 0xf,
 399		.invert = 0,
 400	},
 401	{
 402		.shift = 4,
 403		.reg = PCMD3180_REG_CH2_FINE_GAIN,
 404		.max = 0xf,
 405		.invert = 0,
 406	},
 407	{
 408		.shift = 4,
 409		.reg = PCMD3180_REG_CH3_FINE_GAIN,
 410		.max = 0xf,
 411		.invert = 0,
 412	},
 413	{
 414		.shift = 4,
 415		.reg = PCMD3180_REG_CH4_FINE_GAIN,
 416		.max = 0xf,
 417		.invert = 0,
 418	},
 419	{
 420		.shift = 4,
 421		.reg = PCMD3180_REG_CH5_FINE_GAIN,
 422		.max = 0xf,
 423		.invert = 0,
 424	},
 425	{
 426		.shift = 4,
 427		.reg = PCMD3180_REG_CH6_FINE_GAIN,
 428		.max = 0xf,
 429		.invert = 0,
 430	},
 431	{
 432		.shift = 4,
 433		.reg = PCMD3180_REG_CH7_FINE_GAIN,
 434		.max = 0xf,
 435		.invert = 0,
 436	},
 437	{
 438		.shift = 4,
 439		.reg = PCMD3180_REG_CH8_FINE_GAIN,
 440		.max = 0xf,
 441		.invert = 0,
 442	}
 443};
 444
 445static const struct pcmdevice_mixer_control taa5412_digi_vol_ctl[] = {
 446	{
 447		.shift = 0,
 448		.reg = TAA5412_REG_CH1_DIGITAL_VOLUME,
 449		.max = 0xff,
 450		.invert = 0,
 451	},
 452	{
 453		.shift = 0,
 454		.reg = TAA5412_REG_CH2_DIGITAL_VOLUME,
 455		.max = 0xff,
 456		.invert = 0,
 457	},
 458	{
 459		.shift = 0,
 460		.reg = TAA5412_REG_CH3_DIGITAL_VOLUME,
 461		.max = 0xff,
 462		.invert = 0,
 463	},
 464	{
 465		.shift = 0,
 466		.reg = TAA5412_REG_CH4_DIGITAL_VOLUME,
 467		.max = 0xff,
 468		.invert = 0,
 469	}
 470};
 471
 472static const struct pcmdevice_mixer_control taa5412_fine_gain_ctl[] = {
 473	{
 474		.shift = 4,
 475		.reg = TAA5412_REG_CH1_FINE_GAIN,
 476		.max = 0xf,
 477		.invert = 0,
 478	},
 479	{
 480		.shift = 4,
 481		.reg = TAA5412_REG_CH2_FINE_GAIN,
 482		.max = 0xf,
 483		.invert = 0,
 484	},
 485	{
 486		.shift = 4,
 487		.reg = TAA5412_REG_CH3_FINE_GAIN,
 488		.max = 0xf,
 489		.invert = 4,
 490	},
 491	{
 492		.shift = 0,
 493		.reg = TAA5412_REG_CH4_FINE_GAIN,
 494		.max = 0xf,
 495		.invert = 4,
 496	}
 497};
 498
 499static const DECLARE_TLV_DB_MINMAX_MUTE(pcmd3140_dig_gain_tlv,
 500	-10000, 2700);
 501static const DECLARE_TLV_DB_MINMAX_MUTE(pcm1690_fine_dig_gain_tlv,
 502	-12750, 0);
 503static const DECLARE_TLV_DB_MINMAX_MUTE(pcm1690_dig_gain_tlv,
 504	-25500, 0);
 505static const DECLARE_TLV_DB_MINMAX_MUTE(pcm9211_dig_gain_tlv,
 506	-11450, 2000);
 507static const DECLARE_TLV_DB_MINMAX_MUTE(adc5120_fgain_tlv,
 508	-10050, 2700);
 509static const DECLARE_TLV_DB_LINEAR(adc5120_chgain_tlv, 0, 4200);
 510static const DECLARE_TLV_DB_MINMAX_MUTE(pcm6260_fgain_tlv,
 511	-10000, 2700);
 512static const DECLARE_TLV_DB_LINEAR(pcm6260_chgain_tlv, 0, 4200);
 513static const DECLARE_TLV_DB_MINMAX_MUTE(taa5412_dig_vol_tlv,
 514	-8050, 4700);
 515static const DECLARE_TLV_DB_LINEAR(taa5412_fine_gain_tlv,
 516	-80, 70);
 517
 518static int pcmdev_change_dev(struct pcmdevice_priv *pcm_priv,
 519	unsigned short dev_no)
 520{
 521	struct i2c_client *client = (struct i2c_client *)pcm_priv->client;
 522	struct regmap *map = pcm_priv->regmap;
 523	int ret;
 524
 525	if (client->addr == pcm_priv->addr[dev_no])
 526		return 0;
 527
 528	client->addr = pcm_priv->addr[dev_no];
 529	/* All pcmdevices share the same regmap, clear the page
 530	 * inside regmap once switching to another pcmdevice.
 531	 * Register 0 at any pages inside pcmdevice is the same
 532	 * one for page-switching.
 533	 */
 534	ret = regmap_write(map, PCMDEVICE_PAGE_SELECT, 0);
 535	if (ret < 0)
 536		dev_err(pcm_priv->dev, "%s: err = %d\n", __func__, ret);
 537
 538	return ret;
 539}
 540
 541static int pcmdev_dev_read(struct pcmdevice_priv *pcm_dev,
 542	unsigned int dev_no, unsigned int reg, unsigned int *val)
 543{
 544	struct regmap *map = pcm_dev->regmap;
 545	int ret;
 546
 547	if (dev_no >= pcm_dev->ndev) {
 548		dev_err(pcm_dev->dev, "%s: no such channel(%d)\n", __func__,
 549			dev_no);
 550		return -EINVAL;
 551	}
 552
 553	ret = pcmdev_change_dev(pcm_dev, dev_no);
 554	if (ret < 0) {
 555		dev_err(pcm_dev->dev, "%s: chg dev err = %d\n", __func__, ret);
 556		return ret;
 557	}
 558
 559	ret = regmap_read(map, reg, val);
 560	if (ret < 0)
 561		dev_err(pcm_dev->dev, "%s: err = %d\n", __func__, ret);
 562
 563	return ret;
 564}
 565
 566static int pcmdev_dev_update_bits(struct pcmdevice_priv *pcm_dev,
 567	unsigned int dev_no, unsigned int reg, unsigned int mask,
 568	unsigned int value)
 569{
 570	struct regmap *map = pcm_dev->regmap;
 571	int ret;
 572
 573	if (dev_no >= pcm_dev->ndev) {
 574		dev_err(pcm_dev->dev, "%s: no such channel(%d)\n", __func__,
 575			dev_no);
 576		return -EINVAL;
 577	}
 578
 579	ret = pcmdev_change_dev(pcm_dev, dev_no);
 580	if (ret < 0) {
 581		dev_err(pcm_dev->dev, "%s: chg dev err = %d\n", __func__, ret);
 582		return ret;
 583	}
 584
 585	ret = regmap_update_bits(map, reg, mask, value);
 586	if (ret < 0)
 587		dev_err(pcm_dev->dev, "%s: update_bits err=%d\n",
 588			__func__, ret);
 589
 590	return ret;
 591}
 592
 593static int pcmdev_get_volsw(struct snd_kcontrol *kcontrol,
 594	struct snd_ctl_elem_value *ucontrol, int vol_ctrl_type)
 595{
 596	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 597	struct pcmdevice_priv *pcm_dev =
 598		snd_soc_component_get_drvdata(component);
 599	struct pcmdevice_mixer_control *mc =
 600		(struct pcmdevice_mixer_control *)kcontrol->private_value;
 601	int max = mc->max, ret;
 602	unsigned int mask = BIT(fls(max)) - 1;
 603	unsigned int dev_no = mc->dev_no;
 604	unsigned int shift = mc->shift;
 605	unsigned int reg = mc->reg;
 606	unsigned int val;
 607
 608	mutex_lock(&pcm_dev->codec_lock);
 609
 610	if (pcm_dev->chip_id == PCM1690) {
 611		ret = pcmdev_dev_read(pcm_dev, dev_no, PCM1690_REG_MODE_CTRL,
 612			&val);
 613		if (ret) {
 614			dev_err(pcm_dev->dev, "%s: read mode err=%d\n",
 615				__func__, ret);
 616			goto out;
 617		}
 618		val &= PCM1690_REG_MODE_CTRL_DAMS_MSK;
 619		/* Set to wide-range mode, before using vol ctrl. */
 620		if (!val && vol_ctrl_type == PCMDEV_PCM1690_VOL_CTRL) {
 621			ucontrol->value.integer.value[0] = -25500;
 622			goto out;
 623		}
 624		/* Set to fine mode, before using fine vol ctrl. */
 625		if (val && vol_ctrl_type == PCMDEV_PCM1690_FINE_VOL_CTRL) {
 626			ucontrol->value.integer.value[0] = -12750;
 627			goto out;
 628		}
 629	}
 630
 631	ret = pcmdev_dev_read(pcm_dev, dev_no, reg, &val);
 632	if (ret) {
 633		dev_err(pcm_dev->dev, "%s: read err=%d\n",
 634			__func__, ret);
 635		goto out;
 636	}
 637
 638	val = (val >> shift) & mask;
 639	val = (val > max) ? max : val;
 640	val = mc->invert ? max - val : val;
 641	ucontrol->value.integer.value[0] = val;
 642out:
 643	mutex_unlock(&pcm_dev->codec_lock);
 644	return ret;
 645}
 646
 647static int pcmdevice_get_volsw(struct snd_kcontrol *kcontrol,
 648	struct snd_ctl_elem_value *ucontrol)
 649{
 650	return pcmdev_get_volsw(kcontrol, ucontrol, PCMDEV_GENERIC_VOL_CTRL);
 651}
 652
 653static int pcm1690_get_volsw(struct snd_kcontrol *kcontrol,
 654	struct snd_ctl_elem_value *ucontrol)
 655{
 656	return pcmdev_get_volsw(kcontrol, ucontrol, PCMDEV_PCM1690_VOL_CTRL);
 657}
 658
 659static int pcm1690_get_finevolsw(struct snd_kcontrol *kcontrol,
 660		struct snd_ctl_elem_value *ucontrol)
 661{
 662	return pcmdev_get_volsw(kcontrol, ucontrol,
 663		PCMDEV_PCM1690_FINE_VOL_CTRL);
 664}
 665
 666static int pcmdev_put_volsw(struct snd_kcontrol *kcontrol,
 667	struct snd_ctl_elem_value *ucontrol, int vol_ctrl_type)
 668{
 669	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 670	struct pcmdevice_priv *pcm_dev =
 671		snd_soc_component_get_drvdata(component);
 672	struct pcmdevice_mixer_control *mc =
 673		(struct pcmdevice_mixer_control *)kcontrol->private_value;
 674	int max = mc->max, rc;
 675	unsigned int mask = BIT(fls(max)) - 1;
 676	unsigned int dev_no = mc->dev_no;
 677	unsigned int shift = mc->shift;
 678	unsigned int val, val_mask;
 679	unsigned int reg = mc->reg;
 680
 681	mutex_lock(&pcm_dev->codec_lock);
 682	val = ucontrol->value.integer.value[0] & mask;
 683	val = (val > max) ? max : val;
 684	val = mc->invert ? max - val : val;
 685	val_mask = mask << shift;
 686	val = val << shift;
 687
 688	switch (vol_ctrl_type) {
 689	case PCMDEV_PCM1690_VOL_CTRL:
 690		val_mask |= PCM1690_REG_MODE_CTRL_DAMS_MSK;
 691		val |= PCM1690_REG_MODE_CTRL_DAMS_WIDE_RANGE;
 692		break;
 693	case PCMDEV_PCM1690_FINE_VOL_CTRL:
 694		val_mask |= PCM1690_REG_MODE_CTRL_DAMS_MSK;
 695		val |= PCM1690_REG_MODE_CTRL_DAMS_FINE_STEP;
 696		break;
 697	}
 698
 699	rc = pcmdev_dev_update_bits(pcm_dev, dev_no, reg, val_mask, val);
 700	if (rc < 0)
 701		dev_err(pcm_dev->dev, "%s: update_bits err = %d\n",
 702			__func__, rc);
 703	else
 704		rc = 1;
 705	mutex_unlock(&pcm_dev->codec_lock);
 706	return rc;
 707}
 708
 709static int pcmdevice_put_volsw(struct snd_kcontrol *kcontrol,
 710	struct snd_ctl_elem_value *ucontrol)
 711{
 712	return pcmdev_put_volsw(kcontrol, ucontrol, PCMDEV_GENERIC_VOL_CTRL);
 713}
 714
 715static int pcm1690_put_volsw(struct snd_kcontrol *kcontrol,
 716	struct snd_ctl_elem_value *ucontrol)
 717{
 718	return pcmdev_put_volsw(kcontrol, ucontrol, PCMDEV_PCM1690_VOL_CTRL);
 719}
 720
 721static int pcm1690_put_finevolsw(struct snd_kcontrol *kcontrol,
 722	struct snd_ctl_elem_value *ucontrol)
 723{
 724	return pcmdev_put_volsw(kcontrol, ucontrol,
 725		PCMDEV_PCM1690_FINE_VOL_CTRL);
 726}
 727
 728static const struct pcmdev_ctrl_info pcmdev_gain_ctl_info[][2] = {
 729	// ADC3120
 730	{
 731		{
 732			.gain = adc5120_chgain_tlv,
 733			.pcmdev_ctrl = adc5120_analog_gain_ctl,
 734			.ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl),
 735			.get = pcmdevice_get_volsw,
 736			.put = pcmdevice_put_volsw,
 737			.pcmdev_ctrl_name_id = 0,
 738		},
 739		{
 740			.gain = adc5120_fgain_tlv,
 741			.pcmdev_ctrl = adc5120_digi_gain_ctl,
 742			.ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl),
 743			.get = pcmdevice_get_volsw,
 744			.put = pcmdevice_put_volsw,
 745			.pcmdev_ctrl_name_id = 1,
 746		},
 747	},
 748	// ADC5120
 749	{
 750		{
 751			.gain = adc5120_chgain_tlv,
 752			.pcmdev_ctrl = adc5120_analog_gain_ctl,
 753			.ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl),
 754			.get = pcmdevice_get_volsw,
 755			.put = pcmdevice_put_volsw,
 756			.pcmdev_ctrl_name_id = 0,
 757		},
 758		{
 759			.gain = adc5120_fgain_tlv,
 760			.pcmdev_ctrl = adc5120_digi_gain_ctl,
 761			.ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl),
 762			.get = pcmdevice_get_volsw,
 763			.put = pcmdevice_put_volsw,
 764			.pcmdev_ctrl_name_id = 1,
 765		},
 766	},
 767	// ADC6120
 768	{
 769		{
 770			.gain = adc5120_chgain_tlv,
 771			.pcmdev_ctrl = adc5120_analog_gain_ctl,
 772			.ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl),
 773			.get = pcmdevice_get_volsw,
 774			.put = pcmdevice_put_volsw,
 775			.pcmdev_ctrl_name_id = 0,
 776		},
 777		{
 778			.gain = adc5120_fgain_tlv,
 779			.pcmdev_ctrl = adc5120_digi_gain_ctl,
 780			.ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl),
 781			.get = pcmdevice_get_volsw,
 782			.put = pcmdevice_put_volsw,
 783			.pcmdev_ctrl_name_id = 1,
 784		},
 785	},
 786	// DIX4192
 787	{
 788		{
 789			.ctrl_array_size = 0,
 790		},
 791		{
 792			.ctrl_array_size = 0,
 793		},
 794	},
 795	// PCM1690
 796	{
 797		{
 798			.gain = pcm1690_fine_dig_gain_tlv,
 799			.pcmdev_ctrl = pcm1690_digi_gain_ctl,
 800			.ctrl_array_size = ARRAY_SIZE(pcm1690_digi_gain_ctl),
 801			.get = pcm1690_get_volsw,
 802			.put = pcm1690_put_volsw,
 803			.pcmdev_ctrl_name_id = 1,
 804		},
 805		{
 806			.gain = pcm1690_dig_gain_tlv,
 807			.pcmdev_ctrl = pcm1690_digi_gain_ctl,
 808			.ctrl_array_size = ARRAY_SIZE(pcm1690_digi_gain_ctl),
 809			.get = pcm1690_get_finevolsw,
 810			.put = pcm1690_put_finevolsw,
 811			.pcmdev_ctrl_name_id = 2,
 812		},
 813	},
 814	// PCM3120
 815	{
 816		{
 817			.gain = adc5120_chgain_tlv,
 818			.pcmdev_ctrl = adc5120_analog_gain_ctl,
 819			.ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl),
 820			.get = pcmdevice_get_volsw,
 821			.put = pcmdevice_put_volsw,
 822			.pcmdev_ctrl_name_id = 0,
 823		},
 824		{
 825			.gain = adc5120_fgain_tlv,
 826			.pcmdev_ctrl = adc5120_digi_gain_ctl,
 827			.ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl),
 828			.get = pcmdevice_get_volsw,
 829			.put = pcmdevice_put_volsw,
 830			.pcmdev_ctrl_name_id = 1,
 831		},
 832	},
 833	// PCM3140
 834	{
 835		{
 836			.gain = pcm6260_chgain_tlv,
 837			.pcmdev_ctrl = pcm6240_analog_gain_ctl,
 838			.ctrl_array_size = ARRAY_SIZE(pcm6240_analog_gain_ctl),
 839			.get = pcmdevice_get_volsw,
 840			.put = pcmdevice_put_volsw,
 841			.pcmdev_ctrl_name_id = 0,
 842		},
 843		{
 844			.gain = pcm6260_fgain_tlv,
 845			.pcmdev_ctrl = pcm6240_digi_gain_ctl,
 846			.ctrl_array_size = ARRAY_SIZE(pcm6240_digi_gain_ctl),
 847			.get = pcmdevice_get_volsw,
 848			.put = pcmdevice_put_volsw,
 849			.pcmdev_ctrl_name_id = 1,
 850		},
 851	},
 852	// PCM5120
 853	{
 854		{
 855			.gain = adc5120_chgain_tlv,
 856			.pcmdev_ctrl = adc5120_analog_gain_ctl,
 857			.ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl),
 858			.get = pcmdevice_get_volsw,
 859			.put = pcmdevice_put_volsw,
 860			.pcmdev_ctrl_name_id = 0,
 861		},
 862		{
 863			.gain = adc5120_fgain_tlv,
 864			.pcmdev_ctrl = adc5120_digi_gain_ctl,
 865			.ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl),
 866			.get = pcmdevice_get_volsw,
 867			.put = pcmdevice_put_volsw,
 868			.pcmdev_ctrl_name_id = 1,
 869		},
 870	},
 871	// PCM5140
 872	{
 873		{
 874			.gain = pcm6260_chgain_tlv,
 875			.pcmdev_ctrl = pcm6240_analog_gain_ctl,
 876			.ctrl_array_size = ARRAY_SIZE(pcm6240_analog_gain_ctl),
 877			.get = pcmdevice_get_volsw,
 878			.put = pcmdevice_put_volsw,
 879			.pcmdev_ctrl_name_id = 0,
 880		},
 881		{
 882			.gain = pcm6260_fgain_tlv,
 883			.pcmdev_ctrl = pcm6240_digi_gain_ctl,
 884			.ctrl_array_size = ARRAY_SIZE(pcm6240_digi_gain_ctl),
 885			.get = pcmdevice_get_volsw,
 886			.put = pcmdevice_put_volsw,
 887			.pcmdev_ctrl_name_id = 1,
 888		},
 889	},
 890	// PCM6120
 891	{
 892		{
 893			.gain = adc5120_chgain_tlv,
 894			.pcmdev_ctrl = adc5120_analog_gain_ctl,
 895			.ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl),
 896			.get = pcmdevice_get_volsw,
 897			.put = pcmdevice_put_volsw,
 898			.pcmdev_ctrl_name_id = 0,
 899		},
 900		{
 901			.gain = adc5120_fgain_tlv,
 902			.pcmdev_ctrl = adc5120_digi_gain_ctl,
 903			.ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl),
 904			.get = pcmdevice_get_volsw,
 905			.put = pcmdevice_put_volsw,
 906			.pcmdev_ctrl_name_id = 1,
 907		},
 908	},
 909	// PCM6140
 910	{
 911		{
 912			.gain = pcm6260_chgain_tlv,
 913			.pcmdev_ctrl = pcm6240_analog_gain_ctl,
 914			.ctrl_array_size = ARRAY_SIZE(pcm6240_analog_gain_ctl),
 915			.get = pcmdevice_get_volsw,
 916			.put = pcmdevice_put_volsw,
 917			.pcmdev_ctrl_name_id = 0,
 918		},
 919		{
 920			.gain = pcm6260_fgain_tlv,
 921			.pcmdev_ctrl = pcm6240_digi_gain_ctl,
 922			.ctrl_array_size = ARRAY_SIZE(pcm6240_digi_gain_ctl),
 923			.get = pcmdevice_get_volsw,
 924			.put = pcmdevice_put_volsw,
 925			.pcmdev_ctrl_name_id = 1,
 926		},
 927	},
 928	// PCM6240
 929	{
 930		{
 931			.gain = pcm6260_chgain_tlv,
 932			.pcmdev_ctrl = pcm6240_analog_gain_ctl,
 933			.ctrl_array_size = ARRAY_SIZE(pcm6240_analog_gain_ctl),
 934			.get = pcmdevice_get_volsw,
 935			.put = pcmdevice_put_volsw,
 936			.pcmdev_ctrl_name_id = 0,
 937		},
 938		{
 939			.gain = pcm6260_fgain_tlv,
 940			.pcmdev_ctrl = pcm6240_digi_gain_ctl,
 941			.ctrl_array_size = ARRAY_SIZE(pcm6240_digi_gain_ctl),
 942			.get = pcmdevice_get_volsw,
 943			.put = pcmdevice_put_volsw,
 944			.pcmdev_ctrl_name_id = 1,
 945		},
 946	},
 947	// PCM6260
 948	{
 949		{
 950			.gain = pcm6260_chgain_tlv,
 951			.pcmdev_ctrl = pcm6260_analog_gain_ctl,
 952			.ctrl_array_size = ARRAY_SIZE(pcm6260_analog_gain_ctl),
 953			.get = pcmdevice_get_volsw,
 954			.put = pcmdevice_put_volsw,
 955			.pcmdev_ctrl_name_id = 0,
 956		},
 957		{
 958			.gain = pcm6260_fgain_tlv,
 959			.pcmdev_ctrl = pcm6260_digi_gain_ctl,
 960			.ctrl_array_size = ARRAY_SIZE(pcm6260_digi_gain_ctl),
 961			.get = pcmdevice_get_volsw,
 962			.put = pcmdevice_put_volsw,
 963			.pcmdev_ctrl_name_id = 1,
 964		},
 965	},
 966	// PCM9211
 967	{
 968		{
 969			.ctrl_array_size = 0,
 970		},
 971		{
 972			.gain = pcm9211_dig_gain_tlv,
 973			.pcmdev_ctrl = pcm9211_digi_gain_ctl,
 974			.ctrl_array_size = ARRAY_SIZE(pcm9211_digi_gain_ctl),
 975			.get = pcmdevice_get_volsw,
 976			.put = pcmdevice_put_volsw,
 977			.pcmdev_ctrl_name_id = 1,
 978		},
 979
 980	},
 981	// PCMD3140
 982	{
 983		{
 984			.gain = taa5412_fine_gain_tlv,
 985			.pcmdev_ctrl = pcmd3140_fine_gain_ctl,
 986			.ctrl_array_size = ARRAY_SIZE(pcmd3140_fine_gain_ctl),
 987			.get = pcmdevice_get_volsw,
 988			.put = pcmdevice_put_volsw,
 989			.pcmdev_ctrl_name_id = 2,
 990		},
 991		{
 992			.gain = pcmd3140_dig_gain_tlv,
 993			.pcmdev_ctrl = pcmd3140_digi_gain_ctl,
 994			.ctrl_array_size = ARRAY_SIZE(pcmd3140_digi_gain_ctl),
 995			.get = pcmdevice_get_volsw,
 996			.put = pcmdevice_put_volsw,
 997			.pcmdev_ctrl_name_id = 1,
 998		},
 999	},
1000	// PCMD3180
1001	{
1002		{
1003			.gain = taa5412_fine_gain_tlv,
1004			.pcmdev_ctrl = pcmd3180_fine_gain_ctl,
1005			.ctrl_array_size = ARRAY_SIZE(pcmd3180_fine_gain_ctl),
1006			.get = pcmdevice_get_volsw,
1007			.put = pcmdevice_put_volsw,
1008			.pcmdev_ctrl_name_id = 2,
1009		},
1010		{
1011			.gain = pcmd3140_dig_gain_tlv,
1012			.pcmdev_ctrl = pcmd3180_digi_gain_ctl,
1013			.ctrl_array_size = ARRAY_SIZE(pcmd3180_digi_gain_ctl),
1014			.get = pcmdevice_get_volsw,
1015			.put = pcmdevice_put_volsw,
1016			.pcmdev_ctrl_name_id = 1,
1017		},
1018	},
1019	// PCMD512X
1020	{
1021		{
1022			.ctrl_array_size = 0,
1023		},
1024		{
1025			.ctrl_array_size = 0,
1026		},
1027	},
1028	// TAA5212
1029	{
1030		{
1031			.gain = taa5412_fine_gain_tlv,
1032			.pcmdev_ctrl = taa5412_fine_gain_ctl,
1033			.ctrl_array_size = ARRAY_SIZE(taa5412_fine_gain_ctl),
1034			.get = pcmdevice_get_volsw,
1035			.put = pcmdevice_put_volsw,
1036			.pcmdev_ctrl_name_id = 2,
1037		},
1038		{
1039			.gain = taa5412_dig_vol_tlv,
1040			.pcmdev_ctrl = taa5412_digi_vol_ctl,
1041			.ctrl_array_size = ARRAY_SIZE(taa5412_digi_vol_ctl),
1042			.get = pcmdevice_get_volsw,
1043			.put = pcmdevice_put_volsw,
1044			.pcmdev_ctrl_name_id = 1,
1045		},
1046	},
1047	// TAA5412
1048	{
1049		{
1050			.gain = taa5412_fine_gain_tlv,
1051			.pcmdev_ctrl = taa5412_fine_gain_ctl,
1052			.ctrl_array_size = ARRAY_SIZE(taa5412_fine_gain_ctl),
1053			.get = pcmdevice_get_volsw,
1054			.put = pcmdevice_put_volsw,
1055			.pcmdev_ctrl_name_id = 2,
1056		},
1057		{
1058			.gain = taa5412_dig_vol_tlv,
1059			.pcmdev_ctrl = taa5412_digi_vol_ctl,
1060			.ctrl_array_size = ARRAY_SIZE(taa5412_digi_vol_ctl),
1061			.get = pcmdevice_get_volsw,
1062			.put = pcmdevice_put_volsw,
1063			.pcmdev_ctrl_name_id = 1,
1064		},
1065	},
1066	// TAD5212
1067	{
1068		{
1069			.ctrl_array_size = 0,
1070		},
1071		{
1072			.ctrl_array_size = 0,
1073		},
1074	},
1075	// TAD5412
1076	{
1077		{
1078			.ctrl_array_size = 0,
1079		},
1080		{
1081			.ctrl_array_size = 0,
1082		},
1083	},
1084};
1085
1086static int pcmdev_dev_bulk_write(struct pcmdevice_priv *pcm_dev,
1087	unsigned int dev_no, unsigned int reg, unsigned char *data,
1088	unsigned int len)
1089{
1090	struct regmap *map = pcm_dev->regmap;
1091	int ret;
1092
1093	if (dev_no >= pcm_dev->ndev) {
1094		dev_err(pcm_dev->dev, "%s: no such channel(%d)\n", __func__,
1095			dev_no);
1096		return -EINVAL;
1097	}
1098
1099	ret = pcmdev_change_dev(pcm_dev, dev_no);
1100	if (ret < 0) {
1101		dev_err(pcm_dev->dev, "%s: chg dev err = %d\n", __func__, ret);
1102		return ret;
1103	}
1104
1105	ret = regmap_bulk_write(map, reg, data, len);
1106	if (ret < 0)
1107		dev_err(pcm_dev->dev, "%s: bulk_write err = %d\n", __func__,
1108			ret);
1109
1110	return ret;
1111}
1112
1113static int pcmdev_dev_write(struct pcmdevice_priv *pcm_dev,
1114	unsigned int dev_no, unsigned int reg, unsigned int value)
1115{
1116	struct regmap *map = pcm_dev->regmap;
1117	int ret;
1118
1119	if (dev_no >= pcm_dev->ndev) {
1120		dev_err(pcm_dev->dev, "%s: no such channel(%d)\n", __func__,
1121			dev_no);
1122		return -EINVAL;
1123	}
1124
1125	ret = pcmdev_change_dev(pcm_dev, dev_no);
1126	if (ret < 0) {
1127		dev_err(pcm_dev->dev, "%s: chg dev err = %d\n", __func__, ret);
1128		return ret;
1129	}
1130
1131	ret = regmap_write(map, reg, value);
1132	if (ret < 0)
1133		dev_err(pcm_dev->dev, "%s: err = %d\n", __func__, ret);
1134
1135	return ret;
1136}
1137
1138static int pcmdevice_info_profile(
1139	struct snd_kcontrol *kcontrol,
1140	struct snd_ctl_elem_info *uinfo)
1141{
1142	struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
1143	struct pcmdevice_priv *pcm_dev =
1144		snd_soc_component_get_drvdata(codec);
1145
1146	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1147	uinfo->count = 1;
1148	uinfo->value.integer.min = 0;
1149	uinfo->value.integer.max = max(0, pcm_dev->regbin.ncfgs - 1);
1150
1151	return 0;
1152}
1153
1154static int pcmdevice_get_profile_id(
1155	struct snd_kcontrol *kcontrol,
1156	struct snd_ctl_elem_value *ucontrol)
1157{
1158	struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
1159	struct pcmdevice_priv *pcm_dev =
1160		snd_soc_component_get_drvdata(codec);
1161
1162	ucontrol->value.integer.value[0] = pcm_dev->cur_conf;
1163
1164	return 0;
1165}
1166
1167static int pcmdevice_set_profile_id(
1168	struct snd_kcontrol *kcontrol,
1169	struct snd_ctl_elem_value *ucontrol)
1170{
1171	struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
1172	struct pcmdevice_priv *pcm_dev =
1173		snd_soc_component_get_drvdata(codec);
1174	int nr_profile = ucontrol->value.integer.value[0];
1175	int max = pcm_dev->regbin.ncfgs - 1;
1176	int ret = 0;
1177
1178	nr_profile = clamp(nr_profile, 0, max);
1179
1180	if (pcm_dev->cur_conf != nr_profile) {
1181		pcm_dev->cur_conf = nr_profile;
1182		ret = 1;
1183	}
1184
1185	return ret;
1186}
1187
1188static int pcmdevice_info_volsw(struct snd_kcontrol *kcontrol,
1189	struct snd_ctl_elem_info *uinfo)
1190{
1191	struct pcmdevice_mixer_control *mc =
1192		(struct pcmdevice_mixer_control *)kcontrol->private_value;
1193
1194	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1195	uinfo->count = 1;
1196	uinfo->value.integer.min = 0;
1197	uinfo->value.integer.max = mc->max;
1198	return 0;
1199}
1200
1201static void pcm9211_sw_rst(struct pcmdevice_priv *pcm_dev)
1202{
1203	int ret, i;
1204
1205	for (i = 0; i < pcm_dev->ndev; i++) {
1206		ret = pcmdev_dev_update_bits(pcm_dev, i,
1207			PCM9211_REG_SW_CTRL, PCM9211_REG_SW_CTRL_MRST_MSK,
1208			PCM9211_REG_SW_CTRL_MRST);
1209		if (ret < 0)
1210			dev_err(pcm_dev->dev, "%s: dev %d swreset fail %d\n",
1211				__func__, i, ret);
1212	}
1213}
1214
1215static void pcmdevice_sw_rst(struct pcmdevice_priv *pcm_dev)
1216{
1217	int ret, i;
1218
1219	for (i = 0; i < pcm_dev->ndev; i++) {
1220		ret = pcmdev_dev_write(pcm_dev, i, PCMDEVICE_REG_SWRESET,
1221			PCMDEVICE_REG_SWRESET_RESET);
1222		if (ret < 0)
1223			dev_err(pcm_dev->dev, "%s: dev %d swreset fail %d\n",
1224				__func__, i, ret);
1225	}
1226}
1227
1228static struct pcmdevice_config_info *pcmdevice_add_config(void *ctxt,
1229	const unsigned char *config_data, unsigned int config_size,
1230	int *status)
1231{
1232	struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt;
1233	struct pcmdevice_config_info *cfg_info;
1234	struct pcmdevice_block_data **bk_da;
1235	unsigned int config_offset = 0, i;
1236
1237	cfg_info = kzalloc(sizeof(struct pcmdevice_config_info), GFP_KERNEL);
1238	if (!cfg_info) {
1239		*status = -ENOMEM;
1240		goto out;
1241	}
1242
1243	if (pcm_dev->regbin.fw_hdr.binary_version_num >= 0x105) {
1244		if (config_offset + 64 > (int)config_size) {
1245			*status = -EINVAL;
1246			dev_err(pcm_dev->dev,
1247				"%s: cfg_name out of boundary\n", __func__);
1248			goto out;
1249		}
1250		memcpy(cfg_info->cfg_name, &config_data[config_offset], 64);
1251		config_offset += 64;
1252	}
1253
1254	if (config_offset + 4 > config_size) {
1255		*status = -EINVAL;
1256		dev_err(pcm_dev->dev, "%s: nblocks out of boundary\n",
1257			__func__);
1258		goto out;
1259	}
1260	cfg_info->nblocks =
1261		get_unaligned_be32(&config_data[config_offset]);
1262	config_offset += 4;
1263
1264	bk_da = cfg_info->blk_data = kcalloc(cfg_info->nblocks,
1265		sizeof(struct pcmdevice_block_data *), GFP_KERNEL);
1266	if (!bk_da) {
1267		*status = -ENOMEM;
1268		goto out;
1269	}
1270	cfg_info->real_nblocks = 0;
1271	for (i = 0; i < cfg_info->nblocks; i++) {
1272		if (config_offset + 12 > config_size) {
1273			*status = -EINVAL;
1274			dev_err(pcm_dev->dev,
1275				"%s: out of boundary i = %d nblocks = %u\n",
1276				__func__, i, cfg_info->nblocks);
1277			break;
1278		}
1279		bk_da[i] = kzalloc(sizeof(struct pcmdevice_block_data),
1280			GFP_KERNEL);
1281		if (!bk_da[i]) {
1282			*status = -ENOMEM;
1283			break;
1284		}
1285		bk_da[i]->dev_idx = config_data[config_offset];
1286		config_offset++;
1287
1288		bk_da[i]->block_type = config_data[config_offset];
1289		config_offset++;
1290
1291		if (bk_da[i]->block_type == PCMDEVICE_BIN_BLK_PRE_POWER_UP) {
1292			if (bk_da[i]->dev_idx == 0)
1293				cfg_info->active_dev =
1294					(1 << pcm_dev->ndev) - 1;
1295			else
1296				cfg_info->active_dev =
1297					1 << (bk_da[i]->dev_idx - 1);
1298		}
1299
1300		bk_da[i]->yram_checksum =
1301			get_unaligned_be16(&config_data[config_offset]);
1302		config_offset += 2;
1303		bk_da[i]->block_size =
1304			get_unaligned_be32(&config_data[config_offset]);
1305		config_offset += 4;
1306
1307		bk_da[i]->n_subblks =
1308			get_unaligned_be32(&config_data[config_offset]);
1309
1310		config_offset += 4;
1311
1312		if (config_offset + bk_da[i]->block_size > config_size) {
1313			*status = -EINVAL;
1314			dev_err(pcm_dev->dev,
1315				"%s: out of boundary: i = %d blks = %u\n",
1316				__func__, i, cfg_info->nblocks);
1317			break;
1318		}
1319
1320		bk_da[i]->regdata = kmemdup(&config_data[config_offset],
1321			bk_da[i]->block_size, GFP_KERNEL);
1322		if (!bk_da[i]->regdata) {
1323			*status = -ENOMEM;
1324			goto out;
1325		}
1326		config_offset += bk_da[i]->block_size;
1327		cfg_info->real_nblocks += 1;
1328	}
1329out:
1330	return cfg_info;
1331}
1332
1333static int pcmdev_gain_ctrl_add(struct pcmdevice_priv *pcm_dev,
1334	int dev_no, int ctl_id)
1335{
1336	struct i2c_adapter *adap = pcm_dev->client->adapter;
1337	struct snd_soc_component *comp = pcm_dev->component;
1338	struct pcmdevice_mixer_control *pcmdev_ctrl;
1339	struct snd_kcontrol_new *pcmdev_controls;
1340	int ret, mix_index = 0, name_id, chn;
1341	unsigned int id = pcm_dev->chip_id;
1342	const int nr_chn =
1343		pcmdev_gain_ctl_info[id][ctl_id].ctrl_array_size;
1344	const char *ctrl_name;
1345	char *name;
1346
1347	if (!nr_chn) {
1348		dev_dbg(pcm_dev->dev, "%s: no gain ctrl for %s\n", __func__,
1349			pcm_dev->dev_name);
1350		return 0;
1351	}
1352
1353	pcmdev_controls = devm_kcalloc(pcm_dev->dev, nr_chn,
1354				       sizeof(struct snd_kcontrol_new), GFP_KERNEL);
1355	if (!pcmdev_controls)
1356		return -ENOMEM;
1357
1358	name_id = pcmdev_gain_ctl_info[id][ctl_id].pcmdev_ctrl_name_id;
1359
1360	ctrl_name = pcmdev_ctrl_name[name_id];
1361
1362	for (chn = 1; chn <= nr_chn; chn++) {
1363		name = devm_kzalloc(pcm_dev->dev,
1364			SNDRV_CTL_ELEM_ID_NAME_MAXLEN, GFP_KERNEL);
1365		if (!name) {
1366			ret = -ENOMEM;
1367			goto out;
1368		}
1369		scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
1370			ctrl_name, pcm_dev->upper_dev_name, adap->nr,
1371			dev_no, chn);
1372		pcmdev_controls[mix_index].tlv.p =
1373			pcmdev_gain_ctl_info[id][ctl_id].gain;
1374		pcmdev_ctrl = devm_kmemdup(pcm_dev->dev,
1375			&pcmdev_gain_ctl_info[id][ctl_id].pcmdev_ctrl[chn - 1],
1376			sizeof(*pcmdev_ctrl), GFP_KERNEL);
1377		if (!pcmdev_ctrl) {
1378			ret = -ENOMEM;
1379			goto out;
1380		}
1381		pcmdev_ctrl->dev_no = dev_no;
1382		pcmdev_controls[mix_index].private_value =
1383			(unsigned long)pcmdev_ctrl;
1384		pcmdev_controls[mix_index].name = name;
1385		pcmdev_controls[mix_index].access =
1386			SNDRV_CTL_ELEM_ACCESS_TLV_READ |
1387			SNDRV_CTL_ELEM_ACCESS_READWRITE;
1388		pcmdev_controls[mix_index].iface =
1389			SNDRV_CTL_ELEM_IFACE_MIXER;
1390		pcmdev_controls[mix_index].info = pcmdevice_info_volsw;
1391		pcmdev_controls[mix_index].get =
1392			pcmdev_gain_ctl_info[id][ctl_id].get;
1393		pcmdev_controls[mix_index].put =
1394			pcmdev_gain_ctl_info[id][ctl_id].put;
1395		mix_index++;
1396	}
1397
1398	ret = snd_soc_add_component_controls(comp, pcmdev_controls, mix_index);
1399	if (ret)
1400		dev_err(pcm_dev->dev, "%s: add_controls err = %d\n",
1401			__func__, ret);
1402out:
1403	return ret;
1404}
1405
1406static int pcmdev_profile_ctrl_add(struct pcmdevice_priv *pcm_dev)
1407{
1408	struct snd_soc_component *comp = pcm_dev->component;
1409	struct i2c_adapter *adap = pcm_dev->client->adapter;
1410	struct snd_kcontrol_new *pcmdev_ctrl;
1411	char *name;
1412	int ret;
1413
1414	pcmdev_ctrl = devm_kzalloc(pcm_dev->dev,
1415		sizeof(struct snd_kcontrol_new), GFP_KERNEL);
1416	if (!pcmdev_ctrl)
1417		return -ENOMEM;
1418
1419	/* Create a mixer item for selecting the active profile */
1420	name = devm_kzalloc(pcm_dev->dev, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
1421		GFP_KERNEL);
1422	if (!name)
1423		return -ENOMEM;
1424
1425	scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
1426		"%s i2c%d Profile id", pcm_dev->upper_dev_name, adap->nr);
1427	pcmdev_ctrl->name = name;
1428	pcmdev_ctrl->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1429	pcmdev_ctrl->info = pcmdevice_info_profile;
1430	pcmdev_ctrl->get = pcmdevice_get_profile_id;
1431	pcmdev_ctrl->put = pcmdevice_set_profile_id;
1432
1433	ret = snd_soc_add_component_controls(comp, pcmdev_ctrl, 1);
1434	if (ret)
1435		dev_err(pcm_dev->dev, "%s: add_controls err = %d\n",
1436			__func__, ret);
1437
1438	return ret;
1439}
1440
1441static void pcmdevice_config_info_remove(void *ctxt)
1442{
1443	struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *) ctxt;
1444	struct pcmdevice_regbin *regbin = &(pcm_dev->regbin);
1445	struct pcmdevice_config_info **cfg_info = regbin->cfg_info;
1446	int i, j;
1447
1448	if (!cfg_info)
1449		return;
1450	for (i = 0; i < regbin->ncfgs; i++) {
1451		if (!cfg_info[i])
1452			continue;
1453		if (cfg_info[i]->blk_data) {
1454			for (j = 0; j < (int)cfg_info[i]->real_nblocks; j++) {
1455				if (!cfg_info[i]->blk_data[j])
1456					continue;
1457				kfree(cfg_info[i]->blk_data[j]->regdata);
1458				kfree(cfg_info[i]->blk_data[j]);
1459			}
1460			kfree(cfg_info[i]->blk_data);
1461		}
1462		kfree(cfg_info[i]);
1463	}
1464	kfree(cfg_info);
1465}
1466
1467static int pcmdev_regbin_ready(const struct firmware *fmw, void *ctxt)
1468{
1469	struct pcmdevice_config_info **cfg_info;
1470	struct pcmdevice_priv *pcm_dev = ctxt;
1471	struct pcmdevice_regbin_hdr *fw_hdr;
1472	struct pcmdevice_regbin *regbin;
1473	unsigned int total_config_sz = 0;
1474	int offset = 0, ret = 0, i;
1475	unsigned char *buf;
1476
1477	regbin = &(pcm_dev->regbin);
1478	fw_hdr = &(regbin->fw_hdr);
1479	if (!fmw || !fmw->data) {
1480		dev_err(pcm_dev->dev, "%s: failed to read %s\n",
1481			__func__, pcm_dev->bin_name);
1482		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1483		ret = -EINVAL;
1484		goto out;
1485	}
1486	buf = (unsigned char *)fmw->data;
1487
1488	fw_hdr->img_sz = get_unaligned_be32(&buf[offset]);
1489	offset += 4;
1490	if (fw_hdr->img_sz != fmw->size) {
1491		dev_err(pcm_dev->dev, "%s: file size(%d) not match %u",
1492			__func__, (int)fmw->size, fw_hdr->img_sz);
1493		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1494		ret = -EINVAL;
1495		goto out;
1496	}
1497
1498	fw_hdr->checksum = get_unaligned_be32(&buf[offset]);
1499	offset += 4;
1500	fw_hdr->binary_version_num = get_unaligned_be32(&buf[offset]);
1501	if (fw_hdr->binary_version_num < 0x103) {
1502		dev_err(pcm_dev->dev, "%s: bin version 0x%04x is out of date",
1503			__func__, fw_hdr->binary_version_num);
1504		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1505		ret = -EINVAL;
1506		goto out;
1507	}
1508	offset += 4;
1509	fw_hdr->drv_fw_version = get_unaligned_be32(&buf[offset]);
1510	offset += 8;
1511	fw_hdr->plat_type = buf[offset];
1512	offset += 1;
1513	fw_hdr->dev_family = buf[offset];
1514	offset += 1;
1515	fw_hdr->reserve = buf[offset];
1516	offset += 1;
1517	fw_hdr->ndev = buf[offset];
1518	offset += 1;
1519	if (fw_hdr->ndev != pcm_dev->ndev) {
1520		dev_err(pcm_dev->dev, "%s: invalid ndev(%u)\n", __func__,
1521			fw_hdr->ndev);
1522		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1523		ret = -EINVAL;
1524		goto out;
1525	}
1526
1527	if (offset + PCMDEVICE_MAX_REGBIN_DEVICES > fw_hdr->img_sz) {
1528		dev_err(pcm_dev->dev, "%s: devs out of boundary!\n", __func__);
1529		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1530		ret = -EINVAL;
1531		goto out;
1532	}
1533
1534	for (i = 0; i < PCMDEVICE_MAX_REGBIN_DEVICES; i++, offset++)
1535		fw_hdr->devs[i] = buf[offset];
1536
1537	fw_hdr->nconfig = get_unaligned_be32(&buf[offset]);
1538	offset += 4;
1539
1540	for (i = 0; i < PCMDEVICE_CONFIG_SUM; i++) {
1541		fw_hdr->config_size[i] = get_unaligned_be32(&buf[offset]);
1542		offset += 4;
1543		total_config_sz += fw_hdr->config_size[i];
1544	}
1545
1546	if (fw_hdr->img_sz - total_config_sz != (unsigned int)offset) {
1547		dev_err(pcm_dev->dev, "%s: bin file error!\n", __func__);
1548		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1549		ret = -EINVAL;
1550		goto out;
1551	}
1552	cfg_info = kcalloc(fw_hdr->nconfig, sizeof(*cfg_info), GFP_KERNEL);
1553	if (!cfg_info) {
1554		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1555		ret = -ENOMEM;
1556		goto out;
1557	}
1558	regbin->cfg_info = cfg_info;
1559	regbin->ncfgs = 0;
1560	for (i = 0; i < (int)fw_hdr->nconfig; i++) {
1561		cfg_info[i] = pcmdevice_add_config(ctxt, &buf[offset],
1562				fw_hdr->config_size[i], &ret);
1563		if (ret) {
1564			/* In case the bin file is partially destroyed. */
1565			if (regbin->ncfgs == 0)
1566				pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1567			break;
1568		}
1569		offset += (int)fw_hdr->config_size[i];
1570		regbin->ncfgs += 1;
1571	}
1572
1573out:
1574	if (pcm_dev->fw_state == PCMDEVICE_FW_LOAD_FAILED) {
1575		dev_err(pcm_dev->dev,
1576			"%s: remove config due to fw load error!\n", __func__);
1577		pcmdevice_config_info_remove(pcm_dev);
1578	}
1579
1580	return ret;
1581}
1582
1583static int pcmdevice_comp_probe(struct snd_soc_component *comp)
1584{
1585	struct pcmdevice_priv *pcm_dev = snd_soc_component_get_drvdata(comp);
1586	struct i2c_adapter *adap = pcm_dev->client->adapter;
1587	const struct firmware *fw_entry = NULL;
1588	int ret, i, j;
1589
1590	mutex_lock(&pcm_dev->codec_lock);
1591
1592	pcm_dev->component = comp;
1593
1594	for (i = 0; i < pcm_dev->ndev; i++) {
1595		for (j = 0; j < 2; j++) {
1596			ret = pcmdev_gain_ctrl_add(pcm_dev, i, j);
1597			if (ret < 0)
1598				goto out;
1599		}
1600	}
1601
1602	if (comp->name_prefix) {
1603		/* There's name_prefix defined in DTS. Bin file name will be
1604		 * name_prefix.bin stores the firmware including register
1605		 * setting and params for different filters inside chips, it
1606		 * must be copied into firmware folder. The same types of
1607		 * pcmdevices sitting on the same i2c bus will be aggregated as
1608		 * one single codec, all of them share the same bin file.
1609		 */
1610		scnprintf(pcm_dev->bin_name, PCMDEVICE_BIN_FILENAME_LEN,
1611			"%s.bin", comp->name_prefix);
1612	} else {
1613		/* There's NO name_prefix defined in DTS. Bin file name will be
1614		 * device-name[defined in pcmdevice_i2c_id]-i2c-bus_id
1615		 * [0,1,...,N]-sum[1,...,4]dev.bin stores the firmware
1616		 * including register setting and params for different filters
1617		 * inside chips, it must be copied into firmware folder. The
1618		 * same types of pcmdevices sitting on the same i2c bus will be
1619		 * aggregated as one single codec, all of them share the same
1620		 * bin file.
1621		 */
1622		scnprintf(pcm_dev->bin_name, PCMDEVICE_BIN_FILENAME_LEN,
1623			"%s-i2c-%d-%udev.bin", pcm_dev->dev_name, adap->nr,
1624			pcm_dev->ndev);
1625	}
1626
1627	ret = request_firmware(&fw_entry, pcm_dev->bin_name, pcm_dev->dev);
1628	if (ret) {
1629		dev_err(pcm_dev->dev, "%s: request %s err = %d\n", __func__,
1630			pcm_dev->bin_name, ret);
1631		goto out;
1632	}
1633
1634	ret = pcmdev_regbin_ready(fw_entry, pcm_dev);
1635	if (ret) {
1636		dev_err(pcm_dev->dev, "%s: %s parse err = %d\n", __func__,
1637			pcm_dev->bin_name, ret);
1638		goto out;
1639	}
1640	ret = pcmdev_profile_ctrl_add(pcm_dev);
1641out:
1642	release_firmware(fw_entry);
1643
1644	mutex_unlock(&pcm_dev->codec_lock);
1645	return ret;
1646}
1647
1648
1649static void pcmdevice_comp_remove(struct snd_soc_component *codec)
1650{
1651	struct pcmdevice_priv *pcm_dev = snd_soc_component_get_drvdata(codec);
1652
1653	if (!pcm_dev)
1654		return;
1655	mutex_lock(&pcm_dev->codec_lock);
1656	pcmdevice_config_info_remove(pcm_dev);
1657	mutex_unlock(&pcm_dev->codec_lock);
1658}
1659
1660static const struct snd_soc_dapm_widget pcmdevice_dapm_widgets[] = {
1661	SND_SOC_DAPM_AIF_IN("ASI", "ASI Playback", 0, SND_SOC_NOPM, 0, 0),
1662	SND_SOC_DAPM_AIF_OUT("ASI1 OUT", "ASI1 Capture",
1663		0, SND_SOC_NOPM, 0, 0),
1664	SND_SOC_DAPM_OUTPUT("OUT"),
1665	SND_SOC_DAPM_INPUT("MIC"),
1666};
1667
1668static const struct snd_soc_dapm_route pcmdevice_audio_map[] = {
1669	{"OUT", NULL, "ASI"},
1670	{"ASI1 OUT", NULL, "MIC"},
1671};
1672
1673static const struct snd_soc_component_driver
1674	soc_codec_driver_pcmdevice = {
1675	.probe			= pcmdevice_comp_probe,
1676	.remove			= pcmdevice_comp_remove,
1677	.dapm_widgets		= pcmdevice_dapm_widgets,
1678	.num_dapm_widgets	= ARRAY_SIZE(pcmdevice_dapm_widgets),
1679	.dapm_routes		= pcmdevice_audio_map,
1680	.num_dapm_routes	= ARRAY_SIZE(pcmdevice_audio_map),
1681	.suspend_bias_off	= 1,
1682	.idle_bias_on		= 0,
1683	.use_pmdown_time	= 1,
1684	.endianness		= 1,
1685};
1686
1687static int pcmdev_single_byte_wr(struct pcmdevice_priv *pcm_dev,
1688	unsigned char *data, int devn, int sublocksize)
1689{
1690	unsigned short len = get_unaligned_be16(&data[2]);
1691	int offset = 2;
1692	int i, ret;
1693
1694	offset += 2;
1695	if (offset + 4 * len > sublocksize) {
1696		dev_err(pcm_dev->dev, "%s: dev-%d byt wr out of boundary\n",
1697			__func__, devn);
1698		return -EINVAL;
1699	}
1700
1701	for (i = 0; i < len; i++) {
1702		ret = pcmdev_dev_write(pcm_dev, devn,
1703			PCMDEVICE_REG(data[offset + 1], data[offset + 2]),
1704			data[offset + 3]);
1705		/* skip this error for next operation or next devices */
1706		if (ret < 0)
1707			dev_err(pcm_dev->dev, "%s: dev-%d single write err\n",
1708				__func__, devn);
1709
1710		offset += 4;
1711	}
1712
1713	return offset;
1714}
1715
1716static int pcmdev_burst_wr(struct pcmdevice_priv *pcm_dev,
1717	unsigned char *data, int devn, int sublocksize)
1718{
1719	unsigned short len = get_unaligned_be16(&data[2]);
1720	int offset = 2;
1721	int ret;
1722
1723	offset += 2;
1724	if (offset + 4 + len > sublocksize) {
1725		dev_err(pcm_dev->dev, "%s: dev-%d burst Out of boundary\n",
1726			__func__, devn);
1727		return -EINVAL;
1728	}
1729	if (len % 4) {
1730		dev_err(pcm_dev->dev, "%s: dev-%d bst-len(%u) not div by 4\n",
1731			__func__, devn, len);
1732		return -EINVAL;
1733	}
1734	ret = pcmdev_dev_bulk_write(pcm_dev, devn,
1735		PCMDEVICE_REG(data[offset + 1], data[offset + 2]),
1736		&(data[offset + 4]), len);
1737	/* skip this error for next devices */
1738	if (ret < 0)
1739		dev_err(pcm_dev->dev, "%s: dev-%d bulk_write err = %d\n",
1740			__func__, devn, ret);
1741
1742	offset += (len + 4);
1743
1744	return offset;
1745}
1746
1747static int pcmdev_delay(struct pcmdevice_priv *pcm_dev,
1748	unsigned char *data, int devn, int sublocksize)
1749{
1750	unsigned int delay_time = 0;
1751	int offset = 2;
1752
1753	if (offset + 2 > sublocksize) {
1754		dev_err(pcm_dev->dev, "%s: dev-%d delay out of boundary\n",
1755			__func__, devn);
1756		return -EINVAL;
1757	}
1758	delay_time = get_unaligned_be16(&data[2]) * 1000;
1759	usleep_range(delay_time, delay_time + 50);
1760	offset += 2;
1761
1762	return offset;
1763}
1764
1765static int pcmdev_bits_wr(struct pcmdevice_priv *pcm_dev,
1766	unsigned char *data, int devn, int sublocksize)
1767{
1768	int offset = 2;
1769	int ret;
1770
1771	if (offset + 6 > sublocksize) {
1772		dev_err(pcm_dev->dev, "%s: dev-%d bit write out of memory\n",
1773			__func__, devn);
1774		return -EINVAL;
1775	}
1776	ret = pcmdev_dev_update_bits(pcm_dev, devn,
1777		PCMDEVICE_REG(data[offset + 3], data[offset + 4]),
1778		data[offset + 1], data[offset + 5]);
1779	/* skip this error for next devices */
1780	if (ret < 0)
1781		dev_err(pcm_dev->dev, "%s: dev-%d update_bits err = %d\n",
1782			__func__, devn, ret);
1783
1784	offset += 6;
1785
1786	return offset;
1787}
1788
1789static int pcmdevice_process_block(void *ctxt, unsigned char *data,
1790	unsigned char dev_idx, int sublocksize)
1791{
1792	struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt;
1793	int devn, dev_end, ret = 0;
1794	unsigned char subblk_typ = data[1];
1795
1796	if (dev_idx) {
1797		devn = dev_idx - 1;
1798		dev_end = dev_idx;
1799	} else {
1800		devn = 0;
1801		dev_end = pcm_dev->ndev;
1802	}
1803
1804	/* loop in case of several devices sharing the same sub-block */
1805	for (; devn < dev_end; devn++) {
1806		switch (subblk_typ) {
1807		case PCMDEVICE_CMD_SING_W:
1808		ret = pcmdev_single_byte_wr(pcm_dev, data, devn, sublocksize);
1809			break;
1810		case PCMDEVICE_CMD_BURST:
1811		ret = pcmdev_burst_wr(pcm_dev, data, devn, sublocksize);
1812			break;
1813		case PCMDEVICE_CMD_DELAY:
1814		ret = pcmdev_delay(pcm_dev, data, devn, sublocksize);
1815			break;
1816		case PCMDEVICE_CMD_FIELD_W:
1817		ret = pcmdev_bits_wr(pcm_dev, data, devn, sublocksize);
1818			break;
1819		default:
1820			break;
1821		}
1822		/*
1823		 * In case of sub-block error, break the loop for the rest of
1824		 * devices.
1825		 */
1826		if (ret < 0)
1827			break;
1828	}
1829
1830	return ret;
1831}
1832
1833static void pcmdevice_select_cfg_blk(void *ctxt, int conf_no,
1834	unsigned char block_type)
1835{
1836	struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt;
1837	struct pcmdevice_regbin *regbin = &(pcm_dev->regbin);
1838	struct pcmdevice_config_info **cfg_info = regbin->cfg_info;
1839	struct pcmdevice_block_data **blk_data;
1840	int j, k;
1841
1842	if (conf_no >= regbin->ncfgs || conf_no < 0 || NULL == cfg_info) {
1843		dev_err(pcm_dev->dev, "%s: conf_no should be less than %u\n",
1844			__func__, regbin->ncfgs);
1845		goto out;
1846	}
1847	blk_data = cfg_info[conf_no]->blk_data;
1848
1849	for (j = 0; j < (int)cfg_info[conf_no]->real_nblocks; j++) {
1850		unsigned int length = 0, ret;
1851
1852		if (block_type > 5 || block_type < 2) {
1853			dev_err(pcm_dev->dev,
1854				"%s: block_type should be out of range\n",
1855				__func__);
1856			goto out;
1857		}
1858		if (block_type != blk_data[j]->block_type)
1859			continue;
1860
1861		for (k = 0; k < (int)blk_data[j]->n_subblks; k++) {
1862			ret = pcmdevice_process_block(pcm_dev,
1863				blk_data[j]->regdata + length,
1864				blk_data[j]->dev_idx,
1865				blk_data[j]->block_size - length);
1866			length += ret;
1867			if (blk_data[j]->block_size < length) {
1868				dev_err(pcm_dev->dev,
1869					"%s: %u %u out of boundary\n",
1870					__func__, length,
1871					blk_data[j]->block_size);
1872				break;
1873			}
1874		}
1875		if (length != blk_data[j]->block_size)
1876			dev_err(pcm_dev->dev, "%s: %u %u size is not same\n",
1877				__func__, length, blk_data[j]->block_size);
1878	}
1879
1880out:
1881	return;
1882}
1883
1884static int pcmdevice_mute(struct snd_soc_dai *dai, int mute, int stream)
1885{
1886	struct snd_soc_component *codec = dai->component;
1887	struct pcmdevice_priv *pcm_dev = snd_soc_component_get_drvdata(codec);
1888	unsigned char block_type;
1889
1890	if (pcm_dev->fw_state == PCMDEVICE_FW_LOAD_FAILED) {
1891		dev_err(pcm_dev->dev, "%s: bin file not loaded\n", __func__);
1892		return -EINVAL;
1893	}
1894
1895	if (mute)
1896		block_type = PCMDEVICE_BIN_BLK_PRE_SHUTDOWN;
1897	else
1898		block_type = PCMDEVICE_BIN_BLK_PRE_POWER_UP;
1899
1900	mutex_lock(&pcm_dev->codec_lock);
1901	pcmdevice_select_cfg_blk(pcm_dev, pcm_dev->cur_conf, block_type);
1902	mutex_unlock(&pcm_dev->codec_lock);
1903	return 0;
1904}
1905
1906static int pcmdevice_hw_params(struct snd_pcm_substream *substream,
1907	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
1908{
1909	struct pcmdevice_priv *pcm_dev = snd_soc_dai_get_drvdata(dai);
1910	unsigned int fsrate;
1911	unsigned int slot_width;
1912	int bclk_rate;
1913	int ret = 0;
1914
1915	fsrate = params_rate(params);
1916	switch (fsrate) {
1917	case 48000:
1918		break;
1919	case 44100:
1920		break;
1921	default:
1922		dev_err(pcm_dev->dev, "%s: incorrect sample rate = %u\n",
1923			__func__, fsrate);
1924		ret = -EINVAL;
1925		goto out;
1926	}
1927
1928	slot_width = params_width(params);
1929	switch (slot_width) {
1930	case 16:
1931		break;
1932	case 20:
1933		break;
1934	case 24:
1935		break;
1936	case 32:
1937		break;
1938	default:
1939		dev_err(pcm_dev->dev, "%s: incorrect slot width = %u\n",
1940			__func__, slot_width);
1941		ret = -EINVAL;
1942		goto out;
1943	}
1944
1945	bclk_rate = snd_soc_params_to_bclk(params);
1946	if (bclk_rate < 0) {
1947		dev_err(pcm_dev->dev, "%s: incorrect bclk rate = %d\n",
1948			__func__, bclk_rate);
1949		ret = bclk_rate;
1950	}
1951
1952out:
1953	return ret;
1954}
1955
1956static const struct snd_soc_dai_ops pcmdevice_dai_ops = {
1957	.mute_stream = pcmdevice_mute,
1958	.hw_params = pcmdevice_hw_params,
1959};
1960
1961static struct snd_soc_dai_driver pcmdevice_dai_driver[] = {
1962	{
1963		.name = "pcmdevice-codec",
1964		.capture = {
1965			.stream_name	 = "Capture",
1966			.channels_min	 = 2,
1967			.channels_max	 = PCMDEVICE_MAX_CHANNELS,
1968			.rates		 = PCMDEVICE_RATES,
1969			.formats	 = PCMDEVICE_FORMATS,
1970		},
1971		.playback = {
1972			.stream_name	 = "Playback",
1973			.channels_min	 = 2,
1974			.channels_max	 = PCMDEVICE_MAX_CHANNELS,
1975			.rates		 = PCMDEVICE_RATES,
1976			.formats	 = PCMDEVICE_FORMATS,
1977		},
1978		.ops = &pcmdevice_dai_ops,
1979		.symmetric_rate = 1,
1980	}
1981};
1982
1983#ifdef CONFIG_OF
1984static const struct of_device_id pcmdevice_of_match[] = {
1985	{ .compatible = "ti,adc3120"  },
1986	{ .compatible = "ti,adc5120"  },
1987	{ .compatible = "ti,adc6120"  },
1988	{ .compatible = "ti,dix4192"  },
1989	{ .compatible = "ti,pcm1690"  },
1990	{ .compatible = "ti,pcm3120"  },
1991	{ .compatible = "ti,pcm3140"  },
1992	{ .compatible = "ti,pcm5120"  },
1993	{ .compatible = "ti,pcm5140"  },
1994	{ .compatible = "ti,pcm6120"  },
1995	{ .compatible = "ti,pcm6140"  },
1996	{ .compatible = "ti,pcm6240"  },
1997	{ .compatible = "ti,pcm6260"  },
1998	{ .compatible = "ti,pcm9211"  },
1999	{ .compatible = "ti,pcmd3140" },
2000	{ .compatible = "ti,pcmd3180" },
2001	{ .compatible = "ti,pcmd512x" },
2002	{ .compatible = "ti,taa5212"  },
2003	{ .compatible = "ti,taa5412"  },
2004	{ .compatible = "ti,tad5212"  },
2005	{ .compatible = "ti,tad5412"  },
2006	{},
2007};
2008MODULE_DEVICE_TABLE(of, pcmdevice_of_match);
2009#endif
2010
2011static const struct regmap_range_cfg pcmdevice_ranges[] = {
2012	{
2013		.range_min = 0,
2014		.range_max = 256 * 128,
2015		.selector_reg = PCMDEVICE_PAGE_SELECT,
2016		.selector_mask = 0xff,
2017		.selector_shift = 0,
2018		.window_start = 0,
2019		.window_len = 128,
2020	},
2021};
2022
2023static const struct regmap_config pcmdevice_i2c_regmap = {
2024	.reg_bits = 8,
2025	.val_bits = 8,
2026	.cache_type = REGCACHE_MAPLE,
2027	.ranges = pcmdevice_ranges,
2028	.num_ranges = ARRAY_SIZE(pcmdevice_ranges),
2029	.max_register = 256 * 128,
2030};
2031
2032static void pcmdevice_remove(struct pcmdevice_priv *pcm_dev)
2033{
2034	if (pcm_dev->irq)
2035		free_irq(pcm_dev->irq, pcm_dev);
2036	mutex_destroy(&pcm_dev->codec_lock);
2037}
2038
2039static char *str_to_upper(char *str)
2040{
2041	char *orig = str;
2042
2043	if (!str)
2044		return NULL;
2045
2046	while (*str) {
2047		*str = toupper(*str);
2048		str++;
2049	}
2050
2051	return orig;
2052}
2053
2054static int pcmdevice_i2c_probe(struct i2c_client *i2c)
2055{
2056	struct pcmdevice_priv *pcm_dev;
2057	struct device_node *np;
2058	unsigned int dev_addrs[PCMDEVICE_MAX_I2C_DEVICES];
2059	int ret = 0, i = 0, ndev = 0;
2060
2061	pcm_dev = devm_kzalloc(&i2c->dev, sizeof(*pcm_dev), GFP_KERNEL);
2062	if (!pcm_dev)
2063		return -ENOMEM;
2064
2065	pcm_dev->chip_id = (uintptr_t)i2c_get_match_data(i2c);
2066
2067	pcm_dev->dev = &i2c->dev;
2068	pcm_dev->client = i2c;
2069
2070	if (pcm_dev->chip_id >= MAX_DEVICE)
2071		pcm_dev->chip_id = 0;
2072
2073	strscpy(pcm_dev->dev_name, pcmdevice_i2c_id[pcm_dev->chip_id].name,
2074		sizeof(pcm_dev->dev_name));
2075
2076	strscpy(pcm_dev->upper_dev_name,
2077		pcmdevice_i2c_id[pcm_dev->chip_id].name,
2078		sizeof(pcm_dev->upper_dev_name));
2079
2080	str_to_upper(pcm_dev->upper_dev_name);
2081
2082	pcm_dev->regmap = devm_regmap_init_i2c(i2c, &pcmdevice_i2c_regmap);
2083	if (IS_ERR(pcm_dev->regmap)) {
2084		ret = PTR_ERR(pcm_dev->regmap);
2085		dev_err(&i2c->dev, "%s: failed to allocate register map: %d\n",
2086			__func__, ret);
2087		goto out;
2088	}
2089
2090	i2c_set_clientdata(i2c, pcm_dev);
2091	mutex_init(&pcm_dev->codec_lock);
2092	np = pcm_dev->dev->of_node;
2093
2094	if (IS_ENABLED(CONFIG_OF)) {
2095		u64 addr;
2096
2097		for (i = 0; i < PCMDEVICE_MAX_I2C_DEVICES; i++) {
2098			if (of_property_read_reg(np, i, &addr, NULL))
2099				break;
2100			dev_addrs[ndev++] = addr;
2101		}
2102	} else {
2103		ndev = 1;
2104		dev_addrs[0] = i2c->addr;
2105	}
2106	pcm_dev->irq = of_irq_get(np, 0);
2107
2108	for (i = 0; i < ndev; i++)
2109		pcm_dev->addr[i] = dev_addrs[i];
2110
2111	pcm_dev->ndev = ndev;
2112
2113	pcm_dev->hw_rst = devm_gpiod_get_optional(&i2c->dev,
2114			"reset-gpios", GPIOD_OUT_HIGH);
2115	/* No reset GPIO, no side-effect */
2116	if (IS_ERR(pcm_dev->hw_rst)) {
2117		if (pcm_dev->chip_id == PCM9211 || pcm_dev->chip_id == PCM1690)
2118			pcm9211_sw_rst(pcm_dev);
2119		else
2120			pcmdevice_sw_rst(pcm_dev);
2121	} else {
2122		gpiod_set_value_cansleep(pcm_dev->hw_rst, 0);
2123		usleep_range(500, 1000);
2124		gpiod_set_value_cansleep(pcm_dev->hw_rst, 1);
2125	}
2126
2127	if (pcm_dev->chip_id == PCM1690)
2128		goto skip_interrupt;
2129	if (pcm_dev->irq) {
2130		dev_dbg(pcm_dev->dev, "irq = %d", pcm_dev->irq);
2131	} else
2132		dev_err(pcm_dev->dev, "No irq provided\n");
2133
2134skip_interrupt:
2135	ret = devm_snd_soc_register_component(&i2c->dev,
2136		&soc_codec_driver_pcmdevice, pcmdevice_dai_driver,
2137		ARRAY_SIZE(pcmdevice_dai_driver));
2138	if (ret < 0)
2139		dev_err(&i2c->dev, "probe register comp failed %d\n", ret);
2140
2141out:
2142	if (ret < 0)
2143		pcmdevice_remove(pcm_dev);
2144	return ret;
2145}
2146
2147static void pcmdevice_i2c_remove(struct i2c_client *i2c)
2148{
2149	struct pcmdevice_priv *pcm_dev = i2c_get_clientdata(i2c);
2150
2151	pcmdevice_remove(pcm_dev);
2152}
2153
2154static struct i2c_driver pcmdevice_i2c_driver = {
2155	.driver = {
2156		.name = "pcmdevice-codec",
2157		.of_match_table = of_match_ptr(pcmdevice_of_match),
2158	},
2159	.probe	= pcmdevice_i2c_probe,
2160	.remove = pcmdevice_i2c_remove,
2161	.id_table = pcmdevice_i2c_id,
2162};
2163module_i2c_driver(pcmdevice_i2c_driver);
2164
2165MODULE_AUTHOR("Shenghao Ding <shenghao-ding@ti.com>");
2166MODULE_DESCRIPTION("ASoC PCM6240 Family Audio ADC/DAC Driver");
2167MODULE_LICENSE("GPL");
~/ Read-only file preview.