Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
   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.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
1143		= snd_soc_kcontrol_component(kcontrol);
1144	struct pcmdevice_priv *pcm_dev =
1145		snd_soc_component_get_drvdata(codec);
1146
1147	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1148	uinfo->count = 1;
1149	uinfo->value.integer.min = 0;
1150	uinfo->value.integer.max = max(0, pcm_dev->regbin.ncfgs - 1);
1151
1152	return 0;
1153}
1154
1155static int pcmdevice_get_profile_id(
1156	struct snd_kcontrol *kcontrol,
1157	struct snd_ctl_elem_value *ucontrol)
1158{
1159	struct snd_soc_component *codec
1160		= snd_soc_kcontrol_component(kcontrol);
1161	struct pcmdevice_priv *pcm_dev =
1162		snd_soc_component_get_drvdata(codec);
1163
1164	ucontrol->value.integer.value[0] = pcm_dev->cur_conf;
1165
1166	return 0;
1167}
1168
1169static int pcmdevice_set_profile_id(
1170	struct snd_kcontrol *kcontrol,
1171	struct snd_ctl_elem_value *ucontrol)
1172{
1173	struct snd_soc_component *codec
1174		= snd_soc_kcontrol_component(kcontrol);
1175	struct pcmdevice_priv *pcm_dev =
1176		snd_soc_component_get_drvdata(codec);
1177	int nr_profile = ucontrol->value.integer.value[0];
1178	int max = pcm_dev->regbin.ncfgs - 1;
1179	int ret = 0;
1180
1181	nr_profile = clamp(nr_profile, 0, max);
1182
1183	if (pcm_dev->cur_conf != nr_profile) {
1184		pcm_dev->cur_conf = nr_profile;
1185		ret = 1;
1186	}
1187
1188	return ret;
1189}
1190
1191static int pcmdevice_info_volsw(struct snd_kcontrol *kcontrol,
1192	struct snd_ctl_elem_info *uinfo)
1193{
1194	struct pcmdevice_mixer_control *mc =
1195		(struct pcmdevice_mixer_control *)kcontrol->private_value;
1196
1197	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1198	uinfo->count = 1;
1199	uinfo->value.integer.min = 0;
1200	uinfo->value.integer.max = mc->max;
1201	return 0;
1202}
1203
1204static void pcm9211_sw_rst(struct pcmdevice_priv *pcm_dev)
1205{
1206	int ret, i;
1207
1208	for (i = 0; i < pcm_dev->ndev; i++) {
1209		ret = pcmdev_dev_update_bits(pcm_dev, i,
1210			PCM9211_REG_SW_CTRL, PCM9211_REG_SW_CTRL_MRST_MSK,
1211			PCM9211_REG_SW_CTRL_MRST);
1212		if (ret < 0)
1213			dev_err(pcm_dev->dev, "%s: dev %d swreset fail %d\n",
1214				__func__, i, ret);
1215	}
1216}
1217
1218static void pcmdevice_sw_rst(struct pcmdevice_priv *pcm_dev)
1219{
1220	int ret, i;
1221
1222	for (i = 0; i < pcm_dev->ndev; i++) {
1223		ret = pcmdev_dev_write(pcm_dev, i, PCMDEVICE_REG_SWRESET,
1224			PCMDEVICE_REG_SWRESET_RESET);
1225		if (ret < 0)
1226			dev_err(pcm_dev->dev, "%s: dev %d swreset fail %d\n",
1227				__func__, i, ret);
1228	}
1229}
1230
1231static struct pcmdevice_config_info *pcmdevice_add_config(void *ctxt,
1232	const unsigned char *config_data, unsigned int config_size,
1233	int *status)
1234{
1235	struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt;
1236	struct pcmdevice_config_info *cfg_info;
1237	struct pcmdevice_block_data **bk_da;
1238	unsigned int config_offset = 0, i;
1239
1240	cfg_info = kzalloc(sizeof(struct pcmdevice_config_info), GFP_KERNEL);
1241	if (!cfg_info) {
1242		*status = -ENOMEM;
1243		goto out;
1244	}
1245
1246	if (pcm_dev->regbin.fw_hdr.binary_version_num >= 0x105) {
1247		if (config_offset + 64 > (int)config_size) {
1248			*status = -EINVAL;
1249			dev_err(pcm_dev->dev,
1250				"%s: cfg_name out of boundary\n", __func__);
1251			goto out;
1252		}
1253		memcpy(cfg_info->cfg_name, &config_data[config_offset], 64);
1254		config_offset += 64;
1255	}
1256
1257	if (config_offset + 4 > config_size) {
1258		*status = -EINVAL;
1259		dev_err(pcm_dev->dev, "%s: nblocks out of boundary\n",
1260			__func__);
1261		goto out;
1262	}
1263	cfg_info->nblocks =
1264		get_unaligned_be32(&config_data[config_offset]);
1265	config_offset += 4;
1266
1267	bk_da = cfg_info->blk_data = kcalloc(cfg_info->nblocks,
1268		sizeof(struct pcmdevice_block_data *), GFP_KERNEL);
1269	if (!bk_da) {
1270		*status = -ENOMEM;
1271		goto out;
1272	}
1273	cfg_info->real_nblocks = 0;
1274	for (i = 0; i < cfg_info->nblocks; i++) {
1275		if (config_offset + 12 > config_size) {
1276			*status = -EINVAL;
1277			dev_err(pcm_dev->dev,
1278				"%s: out of boundary i = %d nblocks = %u\n",
1279				__func__, i, cfg_info->nblocks);
1280			break;
1281		}
1282		bk_da[i] = kzalloc(sizeof(struct pcmdevice_block_data),
1283			GFP_KERNEL);
1284		if (!bk_da[i]) {
1285			*status = -ENOMEM;
1286			break;
1287		}
1288		bk_da[i]->dev_idx = config_data[config_offset];
1289		config_offset++;
1290
1291		bk_da[i]->block_type = config_data[config_offset];
1292		config_offset++;
1293
1294		if (bk_da[i]->block_type == PCMDEVICE_BIN_BLK_PRE_POWER_UP) {
1295			if (bk_da[i]->dev_idx == 0)
1296				cfg_info->active_dev =
1297					(1 << pcm_dev->ndev) - 1;
1298			else
1299				cfg_info->active_dev =
1300					1 << (bk_da[i]->dev_idx - 1);
1301		}
1302
1303		bk_da[i]->yram_checksum =
1304			get_unaligned_be16(&config_data[config_offset]);
1305		config_offset += 2;
1306		bk_da[i]->block_size =
1307			get_unaligned_be32(&config_data[config_offset]);
1308		config_offset += 4;
1309
1310		bk_da[i]->n_subblks =
1311			get_unaligned_be32(&config_data[config_offset]);
1312
1313		config_offset += 4;
1314
1315		if (config_offset + bk_da[i]->block_size > config_size) {
1316			*status = -EINVAL;
1317			dev_err(pcm_dev->dev,
1318				"%s: out of boundary: i = %d blks = %u\n",
1319				__func__, i, cfg_info->nblocks);
1320			break;
1321		}
1322
1323		bk_da[i]->regdata = kmemdup(&config_data[config_offset],
1324			bk_da[i]->block_size, GFP_KERNEL);
1325		if (!bk_da[i]->regdata) {
1326			*status = -ENOMEM;
1327			goto out;
1328		}
1329		config_offset += bk_da[i]->block_size;
1330		cfg_info->real_nblocks += 1;
1331	}
1332out:
1333	return cfg_info;
1334}
1335
1336static int pcmdev_gain_ctrl_add(struct pcmdevice_priv *pcm_dev,
1337	int dev_no, int ctl_id)
1338{
1339	struct i2c_adapter *adap = pcm_dev->client->adapter;
1340	struct snd_soc_component *comp = pcm_dev->component;
1341	struct pcmdevice_mixer_control *pcmdev_ctrl;
1342	struct snd_kcontrol_new *pcmdev_controls;
1343	int ret, mix_index = 0, name_id, chn;
1344	unsigned int id = pcm_dev->chip_id;
1345	const int nr_chn =
1346		pcmdev_gain_ctl_info[id][ctl_id].ctrl_array_size;
1347	const char *ctrl_name;
1348	char *name;
1349
1350	if (!nr_chn) {
1351		dev_dbg(pcm_dev->dev, "%s: no gain ctrl for %s\n", __func__,
1352			pcm_dev->dev_name);
1353		return 0;
1354	}
1355
1356	pcmdev_controls = devm_kzalloc(pcm_dev->dev,
1357		nr_chn * sizeof(struct snd_kcontrol_new), GFP_KERNEL);
1358	if (!pcmdev_controls)
1359		return -ENOMEM;
1360
1361	name_id = pcmdev_gain_ctl_info[id][ctl_id].pcmdev_ctrl_name_id;
1362
1363	ctrl_name = pcmdev_ctrl_name[name_id];
1364
1365	for (chn = 1; chn <= nr_chn; chn++) {
1366		name = devm_kzalloc(pcm_dev->dev,
1367			SNDRV_CTL_ELEM_ID_NAME_MAXLEN, GFP_KERNEL);
1368		if (!name) {
1369			ret = -ENOMEM;
1370			goto out;
1371		}
1372		scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
1373			ctrl_name, pcm_dev->upper_dev_name, adap->nr,
1374			dev_no, chn);
1375		pcmdev_controls[mix_index].tlv.p =
1376			pcmdev_gain_ctl_info[id][ctl_id].gain;
1377		pcmdev_ctrl = devm_kmemdup(pcm_dev->dev,
1378			&pcmdev_gain_ctl_info[id][ctl_id].pcmdev_ctrl[chn - 1],
1379			sizeof(*pcmdev_ctrl), GFP_KERNEL);
1380		if (!pcmdev_ctrl) {
1381			ret = -ENOMEM;
1382			goto out;
1383		}
1384		pcmdev_ctrl->dev_no = dev_no;
1385		pcmdev_controls[mix_index].private_value =
1386			(unsigned long)pcmdev_ctrl;
1387		pcmdev_controls[mix_index].name = name;
1388		pcmdev_controls[mix_index].access =
1389			SNDRV_CTL_ELEM_ACCESS_TLV_READ |
1390			SNDRV_CTL_ELEM_ACCESS_READWRITE;
1391		pcmdev_controls[mix_index].iface =
1392			SNDRV_CTL_ELEM_IFACE_MIXER;
1393		pcmdev_controls[mix_index].info = pcmdevice_info_volsw;
1394		pcmdev_controls[mix_index].get =
1395			pcmdev_gain_ctl_info[id][ctl_id].get;
1396		pcmdev_controls[mix_index].put =
1397			pcmdev_gain_ctl_info[id][ctl_id].put;
1398		mix_index++;
1399	}
1400
1401	ret = snd_soc_add_component_controls(comp, pcmdev_controls, mix_index);
1402	if (ret)
1403		dev_err(pcm_dev->dev, "%s: add_controls err = %d\n",
1404			__func__, ret);
1405out:
1406	return ret;
1407}
1408
1409static int pcmdev_profile_ctrl_add(struct pcmdevice_priv *pcm_dev)
1410{
1411	struct snd_soc_component *comp = pcm_dev->component;
1412	struct i2c_adapter *adap = pcm_dev->client->adapter;
1413	struct snd_kcontrol_new *pcmdev_ctrl;
1414	char *name;
1415	int ret;
1416
1417	pcmdev_ctrl = devm_kzalloc(pcm_dev->dev,
1418		sizeof(struct snd_kcontrol_new), GFP_KERNEL);
1419	if (!pcmdev_ctrl)
1420		return -ENOMEM;
1421
1422	/* Create a mixer item for selecting the active profile */
1423	name = devm_kzalloc(pcm_dev->dev, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
1424		GFP_KERNEL);
1425	if (!name)
1426		return -ENOMEM;
1427
1428	scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
1429		"%s i2c%d Profile id", pcm_dev->upper_dev_name, adap->nr);
1430	pcmdev_ctrl->name = name;
1431	pcmdev_ctrl->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1432	pcmdev_ctrl->info = pcmdevice_info_profile;
1433	pcmdev_ctrl->get = pcmdevice_get_profile_id;
1434	pcmdev_ctrl->put = pcmdevice_set_profile_id;
1435
1436	ret = snd_soc_add_component_controls(comp, pcmdev_ctrl, 1);
1437	if (ret)
1438		dev_err(pcm_dev->dev, "%s: add_controls err = %d\n",
1439			__func__, ret);
1440
1441	return ret;
1442}
1443
1444static void pcmdevice_config_info_remove(void *ctxt)
1445{
1446	struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *) ctxt;
1447	struct pcmdevice_regbin *regbin = &(pcm_dev->regbin);
1448	struct pcmdevice_config_info **cfg_info = regbin->cfg_info;
1449	int i, j;
1450
1451	if (!cfg_info)
1452		return;
1453	for (i = 0; i < regbin->ncfgs; i++) {
1454		if (!cfg_info[i])
1455			continue;
1456		if (cfg_info[i]->blk_data) {
1457			for (j = 0; j < (int)cfg_info[i]->real_nblocks; j++) {
1458				if (!cfg_info[i]->blk_data[j])
1459					continue;
1460				kfree(cfg_info[i]->blk_data[j]->regdata);
1461				kfree(cfg_info[i]->blk_data[j]);
1462			}
1463			kfree(cfg_info[i]->blk_data);
1464		}
1465		kfree(cfg_info[i]);
1466	}
1467	kfree(cfg_info);
1468}
1469
1470static int pcmdev_regbin_ready(const struct firmware *fmw, void *ctxt)
1471{
1472	struct pcmdevice_config_info **cfg_info;
1473	struct pcmdevice_priv *pcm_dev = ctxt;
1474	struct pcmdevice_regbin_hdr *fw_hdr;
1475	struct pcmdevice_regbin *regbin;
1476	unsigned int total_config_sz = 0;
1477	int offset = 0, ret = 0, i;
1478	unsigned char *buf;
1479
1480	regbin = &(pcm_dev->regbin);
1481	fw_hdr = &(regbin->fw_hdr);
1482	if (!fmw || !fmw->data) {
1483		dev_err(pcm_dev->dev, "%s: failed to read %s\n",
1484			__func__, pcm_dev->bin_name);
1485		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1486		ret = -EINVAL;
1487		goto out;
1488	}
1489	buf = (unsigned char *)fmw->data;
1490
1491	fw_hdr->img_sz = get_unaligned_be32(&buf[offset]);
1492	offset += 4;
1493	if (fw_hdr->img_sz != fmw->size) {
1494		dev_err(pcm_dev->dev, "%s: file size(%d) not match %u",
1495			__func__, (int)fmw->size, fw_hdr->img_sz);
1496		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1497		ret = -EINVAL;
1498		goto out;
1499	}
1500
1501	fw_hdr->checksum = get_unaligned_be32(&buf[offset]);
1502	offset += 4;
1503	fw_hdr->binary_version_num = get_unaligned_be32(&buf[offset]);
1504	if (fw_hdr->binary_version_num < 0x103) {
1505		dev_err(pcm_dev->dev, "%s: bin version 0x%04x is out of date",
1506			__func__, fw_hdr->binary_version_num);
1507		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1508		ret = -EINVAL;
1509		goto out;
1510	}
1511	offset += 4;
1512	fw_hdr->drv_fw_version = get_unaligned_be32(&buf[offset]);
1513	offset += 8;
1514	fw_hdr->plat_type = buf[offset];
1515	offset += 1;
1516	fw_hdr->dev_family = buf[offset];
1517	offset += 1;
1518	fw_hdr->reserve = buf[offset];
1519	offset += 1;
1520	fw_hdr->ndev = buf[offset];
1521	offset += 1;
1522	if (fw_hdr->ndev != pcm_dev->ndev) {
1523		dev_err(pcm_dev->dev, "%s: invalid ndev(%u)\n", __func__,
1524			fw_hdr->ndev);
1525		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1526		ret = -EINVAL;
1527		goto out;
1528	}
1529
1530	if (offset + PCMDEVICE_MAX_REGBIN_DEVICES > fw_hdr->img_sz) {
1531		dev_err(pcm_dev->dev, "%s: devs out of boundary!\n", __func__);
1532		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1533		ret = -EINVAL;
1534		goto out;
1535	}
1536
1537	for (i = 0; i < PCMDEVICE_MAX_REGBIN_DEVICES; i++, offset++)
1538		fw_hdr->devs[i] = buf[offset];
1539
1540	fw_hdr->nconfig = get_unaligned_be32(&buf[offset]);
1541	offset += 4;
1542
1543	for (i = 0; i < PCMDEVICE_CONFIG_SUM; i++) {
1544		fw_hdr->config_size[i] = get_unaligned_be32(&buf[offset]);
1545		offset += 4;
1546		total_config_sz += fw_hdr->config_size[i];
1547	}
1548
1549	if (fw_hdr->img_sz - total_config_sz != (unsigned int)offset) {
1550		dev_err(pcm_dev->dev, "%s: bin file error!\n", __func__);
1551		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1552		ret = -EINVAL;
1553		goto out;
1554	}
1555	cfg_info = kcalloc(fw_hdr->nconfig, sizeof(*cfg_info), GFP_KERNEL);
1556	if (!cfg_info) {
1557		pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1558		ret = -ENOMEM;
1559		goto out;
1560	}
1561	regbin->cfg_info = cfg_info;
1562	regbin->ncfgs = 0;
1563	for (i = 0; i < (int)fw_hdr->nconfig; i++) {
1564		cfg_info[i] = pcmdevice_add_config(ctxt, &buf[offset],
1565				fw_hdr->config_size[i], &ret);
1566		if (ret) {
1567			/* In case the bin file is partially destroyed. */
1568			if (regbin->ncfgs == 0)
1569				pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED;
1570			break;
1571		}
1572		offset += (int)fw_hdr->config_size[i];
1573		regbin->ncfgs += 1;
1574	}
1575
1576out:
1577	if (pcm_dev->fw_state == PCMDEVICE_FW_LOAD_FAILED) {
1578		dev_err(pcm_dev->dev,
1579			"%s: remove config due to fw load error!\n", __func__);
1580		pcmdevice_config_info_remove(pcm_dev);
1581	}
1582
1583	return ret;
1584}
1585
1586static int pcmdevice_comp_probe(struct snd_soc_component *comp)
1587{
1588	struct pcmdevice_priv *pcm_dev = snd_soc_component_get_drvdata(comp);
1589	struct i2c_adapter *adap = pcm_dev->client->adapter;
1590	const struct firmware *fw_entry = NULL;
1591	int ret, i, j;
1592
1593	mutex_lock(&pcm_dev->codec_lock);
1594
1595	pcm_dev->component = comp;
1596
1597	for (i = 0; i < pcm_dev->ndev; i++) {
1598		for (j = 0; j < 2; j++) {
1599			ret = pcmdev_gain_ctrl_add(pcm_dev, i, j);
1600			if (ret < 0)
1601				goto out;
1602		}
1603	}
1604
1605	if (comp->name_prefix) {
1606		/* There's name_prefix defined in DTS. Bin file name will be
1607		 * name_prefix.bin stores the firmware including register
1608		 * setting and params for different filters inside chips, it
1609		 * must be copied into firmware folder. The same types of
1610		 * pcmdevices sitting on the same i2c bus will be aggregated as
1611		 * one single codec, all of them share the same bin file.
1612		 */
1613		scnprintf(pcm_dev->bin_name, PCMDEVICE_BIN_FILENAME_LEN,
1614			"%s.bin", comp->name_prefix);
1615	} else {
1616		/* There's NO name_prefix defined in DTS. Bin file name will be
1617		 * device-name[defined in pcmdevice_i2c_id]-i2c-bus_id
1618		 * [0,1,...,N]-sum[1,...,4]dev.bin stores the firmware
1619		 * including register setting and params for different filters
1620		 * inside chips, it must be copied into firmware folder. The
1621		 * same types of pcmdevices sitting on the same i2c bus will be
1622		 * aggregated as one single codec, all of them share the same
1623		 * bin file.
1624		 */
1625		scnprintf(pcm_dev->bin_name, PCMDEVICE_BIN_FILENAME_LEN,
1626			"%s-i2c-%d-%udev.bin", pcm_dev->dev_name, adap->nr,
1627			pcm_dev->ndev);
1628	}
1629
1630	ret = request_firmware(&fw_entry, pcm_dev->bin_name, pcm_dev->dev);
1631	if (ret) {
1632		dev_err(pcm_dev->dev, "%s: request %s err = %d\n", __func__,
1633			pcm_dev->bin_name, ret);
1634		goto out;
1635	}
1636
1637	ret = pcmdev_regbin_ready(fw_entry, pcm_dev);
1638	if (ret) {
1639		dev_err(pcm_dev->dev, "%s: %s parse err = %d\n", __func__,
1640			pcm_dev->bin_name, ret);
1641		goto out;
1642	}
1643	ret = pcmdev_profile_ctrl_add(pcm_dev);
1644out:
1645	if (fw_entry)
1646		release_firmware(fw_entry);
1647
1648	mutex_unlock(&pcm_dev->codec_lock);
1649	return ret;
1650}
1651
1652
1653static void pcmdevice_comp_remove(struct snd_soc_component *codec)
1654{
1655	struct pcmdevice_priv *pcm_dev = snd_soc_component_get_drvdata(codec);
1656
1657	if (!pcm_dev)
1658		return;
1659	mutex_lock(&pcm_dev->codec_lock);
1660	pcmdevice_config_info_remove(pcm_dev);
1661	mutex_unlock(&pcm_dev->codec_lock);
1662}
1663
1664static const struct snd_soc_dapm_widget pcmdevice_dapm_widgets[] = {
1665	SND_SOC_DAPM_AIF_IN("ASI", "ASI Playback", 0, SND_SOC_NOPM, 0, 0),
1666	SND_SOC_DAPM_AIF_OUT("ASI1 OUT", "ASI1 Capture",
1667		0, SND_SOC_NOPM, 0, 0),
1668	SND_SOC_DAPM_OUTPUT("OUT"),
1669	SND_SOC_DAPM_INPUT("MIC"),
1670};
1671
1672static const struct snd_soc_dapm_route pcmdevice_audio_map[] = {
1673	{"OUT", NULL, "ASI"},
1674	{"ASI1 OUT", NULL, "MIC"},
1675};
1676
1677static const struct snd_soc_component_driver
1678	soc_codec_driver_pcmdevice = {
1679	.probe			= pcmdevice_comp_probe,
1680	.remove			= pcmdevice_comp_remove,
1681	.dapm_widgets		= pcmdevice_dapm_widgets,
1682	.num_dapm_widgets	= ARRAY_SIZE(pcmdevice_dapm_widgets),
1683	.dapm_routes		= pcmdevice_audio_map,
1684	.num_dapm_routes	= ARRAY_SIZE(pcmdevice_audio_map),
1685	.suspend_bias_off	= 1,
1686	.idle_bias_on		= 0,
1687	.use_pmdown_time	= 1,
1688	.endianness		= 1,
1689};
1690
1691static int pcmdev_single_byte_wr(struct pcmdevice_priv *pcm_dev,
1692	unsigned char *data, int devn, int sublocksize)
1693{
1694	unsigned short len = get_unaligned_be16(&data[2]);
1695	int offset = 2;
1696	int i, ret;
1697
1698	offset += 2;
1699	if (offset + 4 * len > sublocksize) {
1700		dev_err(pcm_dev->dev, "%s: dev-%d byt wr out of boundary\n",
1701			__func__, devn);
1702		return -EINVAL;
1703	}
1704
1705	for (i = 0; i < len; i++) {
1706		ret = pcmdev_dev_write(pcm_dev, devn,
1707			PCMDEVICE_REG(data[offset + 1], data[offset + 2]),
1708			data[offset + 3]);
1709		/* skip this error for next operation or next devices */
1710		if (ret < 0)
1711			dev_err(pcm_dev->dev, "%s: dev-%d single write err\n",
1712				__func__, devn);
1713
1714		offset += 4;
1715	}
1716
1717	return offset;
1718}
1719
1720static int pcmdev_burst_wr(struct pcmdevice_priv *pcm_dev,
1721	unsigned char *data, int devn, int sublocksize)
1722{
1723	unsigned short len = get_unaligned_be16(&data[2]);
1724	int offset = 2;
1725	int ret;
1726
1727	offset += 2;
1728	if (offset + 4 + len > sublocksize) {
1729		dev_err(pcm_dev->dev, "%s: dev-%d burst Out of boundary\n",
1730			__func__, devn);
1731		return -EINVAL;
1732	}
1733	if (len % 4) {
1734		dev_err(pcm_dev->dev, "%s: dev-%d bst-len(%u) not div by 4\n",
1735			__func__, devn, len);
1736		return -EINVAL;
1737	}
1738	ret = pcmdev_dev_bulk_write(pcm_dev, devn,
1739		PCMDEVICE_REG(data[offset + 1], data[offset + 2]),
1740		&(data[offset + 4]), len);
1741	/* skip this error for next devices */
1742	if (ret < 0)
1743		dev_err(pcm_dev->dev, "%s: dev-%d bulk_write err = %d\n",
1744			__func__, devn, ret);
1745
1746	offset += (len + 4);
1747
1748	return offset;
1749}
1750
1751static int pcmdev_delay(struct pcmdevice_priv *pcm_dev,
1752	unsigned char *data, int devn, int sublocksize)
1753{
1754	unsigned int delay_time = 0;
1755	int offset = 2;
1756
1757	if (offset + 2 > sublocksize) {
1758		dev_err(pcm_dev->dev, "%s: dev-%d delay out of boundary\n",
1759			__func__, devn);
1760		return -EINVAL;
1761	}
1762	delay_time = get_unaligned_be16(&data[2]) * 1000;
1763	usleep_range(delay_time, delay_time + 50);
1764	offset += 2;
1765
1766	return offset;
1767}
1768
1769static int pcmdev_bits_wr(struct pcmdevice_priv *pcm_dev,
1770	unsigned char *data, int devn, int sublocksize)
1771{
1772	int offset = 2;
1773	int ret;
1774
1775	if (offset + 6 > sublocksize) {
1776		dev_err(pcm_dev->dev, "%s: dev-%d bit write out of memory\n",
1777			__func__, devn);
1778		return -EINVAL;
1779	}
1780	ret = pcmdev_dev_update_bits(pcm_dev, devn,
1781		PCMDEVICE_REG(data[offset + 3], data[offset + 4]),
1782		data[offset + 1], data[offset + 5]);
1783	/* skip this error for next devices */
1784	if (ret < 0)
1785		dev_err(pcm_dev->dev, "%s: dev-%d update_bits err = %d\n",
1786			__func__, devn, ret);
1787
1788	offset += 6;
1789
1790	return offset;
1791}
1792
1793static int pcmdevice_process_block(void *ctxt, unsigned char *data,
1794	unsigned char dev_idx, int sublocksize)
1795{
1796	struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt;
1797	int devn, dev_end, ret = 0;
1798	unsigned char subblk_typ = data[1];
1799
1800	if (dev_idx) {
1801		devn = dev_idx - 1;
1802		dev_end = dev_idx;
1803	} else {
1804		devn = 0;
1805		dev_end = pcm_dev->ndev;
1806	}
1807
1808	/* loop in case of several devices sharing the same sub-block */
1809	for (; devn < dev_end; devn++) {
1810		switch (subblk_typ) {
1811		case PCMDEVICE_CMD_SING_W:
1812		ret = pcmdev_single_byte_wr(pcm_dev, data, devn, sublocksize);
1813			break;
1814		case PCMDEVICE_CMD_BURST:
1815		ret = pcmdev_burst_wr(pcm_dev, data, devn, sublocksize);
1816			break;
1817		case PCMDEVICE_CMD_DELAY:
1818		ret = pcmdev_delay(pcm_dev, data, devn, sublocksize);
1819			break;
1820		case PCMDEVICE_CMD_FIELD_W:
1821		ret = pcmdev_bits_wr(pcm_dev, data, devn, sublocksize);
1822			break;
1823		default:
1824			break;
1825		}
1826		/*
1827		 * In case of sub-block error, break the loop for the rest of
1828		 * devices.
1829		 */
1830		if (ret < 0)
1831			break;
1832	}
1833
1834	return ret;
1835}
1836
1837static void pcmdevice_select_cfg_blk(void *ctxt, int conf_no,
1838	unsigned char block_type)
1839{
1840	struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt;
1841	struct pcmdevice_regbin *regbin = &(pcm_dev->regbin);
1842	struct pcmdevice_config_info **cfg_info = regbin->cfg_info;
1843	struct pcmdevice_block_data **blk_data;
1844	int j, k;
1845
1846	if (conf_no >= regbin->ncfgs || conf_no < 0 || NULL == cfg_info) {
1847		dev_err(pcm_dev->dev, "%s: conf_no should be less than %u\n",
1848			__func__, regbin->ncfgs);
1849		goto out;
1850	}
1851	blk_data = cfg_info[conf_no]->blk_data;
1852
1853	for (j = 0; j < (int)cfg_info[conf_no]->real_nblocks; j++) {
1854		unsigned int length = 0, ret;
1855
1856		if (block_type > 5 || block_type < 2) {
1857			dev_err(pcm_dev->dev,
1858				"%s: block_type should be out of range\n",
1859				__func__);
1860			goto out;
1861		}
1862		if (block_type != blk_data[j]->block_type)
1863			continue;
1864
1865		for (k = 0; k < (int)blk_data[j]->n_subblks; k++) {
1866			ret = pcmdevice_process_block(pcm_dev,
1867				blk_data[j]->regdata + length,
1868				blk_data[j]->dev_idx,
1869				blk_data[j]->block_size - length);
1870			length += ret;
1871			if (blk_data[j]->block_size < length) {
1872				dev_err(pcm_dev->dev,
1873					"%s: %u %u out of boundary\n",
1874					__func__, length,
1875					blk_data[j]->block_size);
1876				break;
1877			}
1878		}
1879		if (length != blk_data[j]->block_size)
1880			dev_err(pcm_dev->dev, "%s: %u %u size is not same\n",
1881				__func__, length, blk_data[j]->block_size);
1882	}
1883
1884out:
1885	return;
1886}
1887
1888static int pcmdevice_mute(struct snd_soc_dai *dai, int mute, int stream)
1889{
1890	struct snd_soc_component *codec = dai->component;
1891	struct pcmdevice_priv *pcm_dev = snd_soc_component_get_drvdata(codec);
1892	unsigned char block_type;
1893
1894	if (pcm_dev->fw_state == PCMDEVICE_FW_LOAD_FAILED) {
1895		dev_err(pcm_dev->dev, "%s: bin file not loaded\n", __func__);
1896		return -EINVAL;
1897	}
1898
1899	if (mute)
1900		block_type = PCMDEVICE_BIN_BLK_PRE_SHUTDOWN;
1901	else
1902		block_type = PCMDEVICE_BIN_BLK_PRE_POWER_UP;
1903
1904	mutex_lock(&pcm_dev->codec_lock);
1905	pcmdevice_select_cfg_blk(pcm_dev, pcm_dev->cur_conf, block_type);
1906	mutex_unlock(&pcm_dev->codec_lock);
1907	return 0;
1908}
1909
1910static int pcmdevice_hw_params(struct snd_pcm_substream *substream,
1911	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
1912{
1913	struct pcmdevice_priv *pcm_dev = snd_soc_dai_get_drvdata(dai);
1914	unsigned int fsrate;
1915	unsigned int slot_width;
1916	int bclk_rate;
1917	int ret = 0;
1918
1919	fsrate = params_rate(params);
1920	switch (fsrate) {
1921	case 48000:
1922		break;
1923	case 44100:
1924		break;
1925	default:
1926		dev_err(pcm_dev->dev, "%s: incorrect sample rate = %u\n",
1927			__func__, fsrate);
1928		ret = -EINVAL;
1929		goto out;
1930	}
1931
1932	slot_width = params_width(params);
1933	switch (slot_width) {
1934	case 16:
1935		break;
1936	case 20:
1937		break;
1938	case 24:
1939		break;
1940	case 32:
1941		break;
1942	default:
1943		dev_err(pcm_dev->dev, "%s: incorrect slot width = %u\n",
1944			__func__, slot_width);
1945		ret = -EINVAL;
1946		goto out;
1947	}
1948
1949	bclk_rate = snd_soc_params_to_bclk(params);
1950	if (bclk_rate < 0) {
1951		dev_err(pcm_dev->dev, "%s: incorrect bclk rate = %d\n",
1952			__func__, bclk_rate);
1953		ret = bclk_rate;
1954	}
1955
1956out:
1957	return ret;
1958}
1959
1960static const struct snd_soc_dai_ops pcmdevice_dai_ops = {
1961	.mute_stream = pcmdevice_mute,
1962	.hw_params = pcmdevice_hw_params,
1963};
1964
1965static struct snd_soc_dai_driver pcmdevice_dai_driver[] = {
1966	{
1967		.name = "pcmdevice-codec",
1968		.capture = {
1969			.stream_name	 = "Capture",
1970			.channels_min	 = 2,
1971			.channels_max	 = PCMDEVICE_MAX_CHANNELS,
1972			.rates		 = PCMDEVICE_RATES,
1973			.formats	 = PCMDEVICE_FORMATS,
1974		},
1975		.playback = {
1976			.stream_name	 = "Playback",
1977			.channels_min	 = 2,
1978			.channels_max	 = PCMDEVICE_MAX_CHANNELS,
1979			.rates		 = PCMDEVICE_RATES,
1980			.formats	 = PCMDEVICE_FORMATS,
1981		},
1982		.ops = &pcmdevice_dai_ops,
1983		.symmetric_rate = 1,
1984	}
1985};
1986
1987#ifdef CONFIG_OF
1988static const struct of_device_id pcmdevice_of_match[] = {
1989	{ .compatible = "ti,adc3120"  },
1990	{ .compatible = "ti,adc5120"  },
1991	{ .compatible = "ti,adc6120"  },
1992	{ .compatible = "ti,dix4192"  },
1993	{ .compatible = "ti,pcm1690"  },
1994	{ .compatible = "ti,pcm3120"  },
1995	{ .compatible = "ti,pcm3140"  },
1996	{ .compatible = "ti,pcm5120"  },
1997	{ .compatible = "ti,pcm5140"  },
1998	{ .compatible = "ti,pcm6120"  },
1999	{ .compatible = "ti,pcm6140"  },
2000	{ .compatible = "ti,pcm6240"  },
2001	{ .compatible = "ti,pcm6260"  },
2002	{ .compatible = "ti,pcm9211"  },
2003	{ .compatible = "ti,pcmd3140" },
2004	{ .compatible = "ti,pcmd3180" },
2005	{ .compatible = "ti,pcmd512x" },
2006	{ .compatible = "ti,taa5212"  },
2007	{ .compatible = "ti,taa5412"  },
2008	{ .compatible = "ti,tad5212"  },
2009	{ .compatible = "ti,tad5412"  },
2010	{},
2011};
2012MODULE_DEVICE_TABLE(of, pcmdevice_of_match);
2013#endif
2014
2015static const struct regmap_range_cfg pcmdevice_ranges[] = {
2016	{
2017		.range_min = 0,
2018		.range_max = 256 * 128,
2019		.selector_reg = PCMDEVICE_PAGE_SELECT,
2020		.selector_mask = 0xff,
2021		.selector_shift = 0,
2022		.window_start = 0,
2023		.window_len = 128,
2024	},
2025};
2026
2027static const struct regmap_config pcmdevice_i2c_regmap = {
2028	.reg_bits = 8,
2029	.val_bits = 8,
2030	.cache_type = REGCACHE_MAPLE,
2031	.ranges = pcmdevice_ranges,
2032	.num_ranges = ARRAY_SIZE(pcmdevice_ranges),
2033	.max_register = 256 * 128,
2034};
2035
2036static void pcmdevice_remove(struct pcmdevice_priv *pcm_dev)
2037{
2038	if (gpio_is_valid(pcm_dev->irq_info.gpio)) {
2039		gpio_free(pcm_dev->irq_info.gpio);
2040		free_irq(pcm_dev->irq_info.nmb, pcm_dev);
2041	}
2042	mutex_destroy(&pcm_dev->codec_lock);
2043}
2044
2045static char *str_to_upper(char *str)
2046{
2047	char *orig = str;
2048
2049	if (!str)
2050		return NULL;
2051
2052	while (*str) {
2053		*str = toupper(*str);
2054		str++;
2055	}
2056
2057	return orig;
2058}
2059
2060static int pcmdevice_i2c_probe(struct i2c_client *i2c)
2061{
2062	const struct i2c_device_id *id = i2c_match_id(pcmdevice_i2c_id, i2c);
2063	struct pcmdevice_priv *pcm_dev;
2064	struct device_node *np;
2065	unsigned int dev_addrs[PCMDEVICE_MAX_I2C_DEVICES];
2066	int ret = 0, i = 0, ndev = 0;
2067
2068	pcm_dev = devm_kzalloc(&i2c->dev, sizeof(*pcm_dev), GFP_KERNEL);
2069	if (!pcm_dev)
2070		return -ENOMEM;
2071
2072	pcm_dev->chip_id = (id != NULL) ? id->driver_data : 0;
2073
2074	pcm_dev->dev = &i2c->dev;
2075	pcm_dev->client = i2c;
2076
2077	if (pcm_dev->chip_id >= MAX_DEVICE)
2078		pcm_dev->chip_id = 0;
2079
2080	strscpy(pcm_dev->dev_name, pcmdevice_i2c_id[pcm_dev->chip_id].name,
2081		sizeof(pcm_dev->dev_name));
2082
2083	strscpy(pcm_dev->upper_dev_name,
2084		pcmdevice_i2c_id[pcm_dev->chip_id].name,
2085		sizeof(pcm_dev->upper_dev_name));
2086
2087	str_to_upper(pcm_dev->upper_dev_name);
2088
2089	pcm_dev->regmap = devm_regmap_init_i2c(i2c, &pcmdevice_i2c_regmap);
2090	if (IS_ERR(pcm_dev->regmap)) {
2091		ret = PTR_ERR(pcm_dev->regmap);
2092		dev_err(&i2c->dev, "%s: failed to allocate register map: %d\n",
2093			__func__, ret);
2094		goto out;
2095	}
2096
2097	i2c_set_clientdata(i2c, pcm_dev);
2098	mutex_init(&pcm_dev->codec_lock);
2099	np = pcm_dev->dev->of_node;
2100
2101	if (IS_ENABLED(CONFIG_OF)) {
2102		u64 addr;
2103
2104		for (i = 0; i < PCMDEVICE_MAX_I2C_DEVICES; i++) {
2105			if (of_property_read_reg(np, i, &addr, NULL))
2106				break;
2107			dev_addrs[ndev++] = addr;
2108		}
2109	} else {
2110		ndev = 1;
2111		dev_addrs[0] = i2c->addr;
2112	}
2113	pcm_dev->irq_info.gpio = of_irq_get(np, 0);
2114
2115	for (i = 0; i < ndev; i++)
2116		pcm_dev->addr[i] = dev_addrs[i];
2117
2118	pcm_dev->ndev = ndev;
2119
2120	pcm_dev->hw_rst = devm_gpiod_get_optional(&i2c->dev,
2121			"reset-gpios", GPIOD_OUT_HIGH);
2122	/* No reset GPIO, no side-effect */
2123	if (IS_ERR(pcm_dev->hw_rst)) {
2124		if (pcm_dev->chip_id == PCM9211 || pcm_dev->chip_id == PCM1690)
2125			pcm9211_sw_rst(pcm_dev);
2126		else
2127			pcmdevice_sw_rst(pcm_dev);
2128	} else {
2129		gpiod_set_value_cansleep(pcm_dev->hw_rst, 0);
2130		usleep_range(500, 1000);
2131		gpiod_set_value_cansleep(pcm_dev->hw_rst, 1);
2132	}
2133
2134	if (pcm_dev->chip_id == PCM1690)
2135		goto skip_interrupt;
2136	if (gpio_is_valid(pcm_dev->irq_info.gpio)) {
2137		dev_dbg(pcm_dev->dev, "irq-gpio = %d", pcm_dev->irq_info.gpio);
2138
2139		ret = gpio_request(pcm_dev->irq_info.gpio, "PCMDEV-IRQ");
2140		if (!ret) {
2141			int gpio = pcm_dev->irq_info.gpio;
2142
2143			gpio_direction_input(gpio);
2144			pcm_dev->irq_info.nmb = gpio_to_irq(gpio);
2145
2146		} else
2147			dev_err(pcm_dev->dev, "%s: GPIO %d request error\n",
2148				__func__, pcm_dev->irq_info.gpio);
2149	} else
2150		dev_err(pcm_dev->dev, "Looking up irq-gpio failed %d\n",
2151			pcm_dev->irq_info.gpio);
2152
2153skip_interrupt:
2154	ret = devm_snd_soc_register_component(&i2c->dev,
2155		&soc_codec_driver_pcmdevice, pcmdevice_dai_driver,
2156		ARRAY_SIZE(pcmdevice_dai_driver));
2157	if (ret < 0)
2158		dev_err(&i2c->dev, "probe register comp failed %d\n", ret);
2159
2160out:
2161	if (ret < 0)
2162		pcmdevice_remove(pcm_dev);
2163	return ret;
2164}
2165
2166static void pcmdevice_i2c_remove(struct i2c_client *i2c)
2167{
2168	struct pcmdevice_priv *pcm_dev = i2c_get_clientdata(i2c);
2169
2170	pcmdevice_remove(pcm_dev);
2171}
2172
2173static struct i2c_driver pcmdevice_i2c_driver = {
2174	.driver = {
2175		.name = "pcmdevice-codec",
2176		.of_match_table = of_match_ptr(pcmdevice_of_match),
2177	},
2178	.probe	= pcmdevice_i2c_probe,
2179	.remove = pcmdevice_i2c_remove,
2180	.id_table = pcmdevice_i2c_id,
2181};
2182module_i2c_driver(pcmdevice_i2c_driver);
2183
2184MODULE_AUTHOR("Shenghao Ding <shenghao-ding@ti.com>");
2185MODULE_DESCRIPTION("ASoC PCM6240 Family Audio ADC/DAC Driver");
2186MODULE_LICENSE("GPL");