343 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * AK4104 ALSA SoC (ASoC) driver4 *5 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>6 */7 8#include <linux/mod_devicetable.h>9#include <linux/module.h>10#include <linux/slab.h>11#include <linux/spi/spi.h>12#include <linux/gpio/consumer.h>13#include <linux/regulator/consumer.h>14#include <sound/asoundef.h>15#include <sound/core.h>16#include <sound/soc.h>17#include <sound/initval.h>18 19/* AK4104 registers addresses */20#define AK4104_REG_CONTROL1 0x0021#define AK4104_REG_RESERVED 0x0122#define AK4104_REG_CONTROL2 0x0223#define AK4104_REG_TX 0x0324#define AK4104_REG_CHN_STATUS(x) ((x) + 0x04)25#define AK4104_NUM_REGS 1026 27#define AK4104_REG_MASK 0x1f28#define AK4104_READ 0xc029#define AK4104_WRITE 0xe030#define AK4104_RESERVED_VAL 0x5b31 32/* Bit masks for AK4104 registers */33#define AK4104_CONTROL1_RSTN (1 << 0)34#define AK4104_CONTROL1_PW (1 << 1)35#define AK4104_CONTROL1_DIF0 (1 << 2)36#define AK4104_CONTROL1_DIF1 (1 << 3)37 38#define AK4104_CONTROL2_SEL0 (1 << 0)39#define AK4104_CONTROL2_SEL1 (1 << 1)40#define AK4104_CONTROL2_MODE (1 << 2)41 42#define AK4104_TX_TXE (1 << 0)43#define AK4104_TX_V (1 << 1)44 45struct ak4104_private {46 struct regmap *regmap;47 struct regulator *regulator;48};49 50static const struct snd_soc_dapm_widget ak4104_dapm_widgets[] = {51SND_SOC_DAPM_PGA("TXE", AK4104_REG_TX, AK4104_TX_TXE, 0, NULL, 0),52 53SND_SOC_DAPM_OUTPUT("TX"),54};55 56static const struct snd_soc_dapm_route ak4104_dapm_routes[] = {57 { "TXE", NULL, "Playback" },58 { "TX", NULL, "TXE" },59};60 61static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai,62 unsigned int format)63{64 struct snd_soc_component *component = codec_dai->component;65 struct ak4104_private *ak4104 = snd_soc_component_get_drvdata(component);66 int val = 0;67 int ret;68 69 /* set DAI format */70 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {71 case SND_SOC_DAIFMT_RIGHT_J:72 break;73 case SND_SOC_DAIFMT_LEFT_J:74 val |= AK4104_CONTROL1_DIF0;75 break;76 case SND_SOC_DAIFMT_I2S:77 val |= AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1;78 break;79 default:80 dev_err(component->dev, "invalid dai format\n");81 return -EINVAL;82 }83 84 /* This device can only be consumer */85 if ((format & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_CBC_CFC)86 return -EINVAL;87 88 ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1,89 AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1,90 val);91 if (ret < 0)92 return ret;93 94 return 0;95}96 97static int ak4104_hw_params(struct snd_pcm_substream *substream,98 struct snd_pcm_hw_params *params,99 struct snd_soc_dai *dai)100{101 struct snd_soc_component *component = dai->component;102 struct ak4104_private *ak4104 = snd_soc_component_get_drvdata(component);103 int ret, val = 0;104 105 /* set the IEC958 bits: consumer mode, no copyright bit */106 val |= IEC958_AES0_CON_NOT_COPYRIGHT;107 regmap_write(ak4104->regmap, AK4104_REG_CHN_STATUS(0), val);108 109 val = 0;110 111 switch (params_rate(params)) {112 case 22050:113 val |= IEC958_AES3_CON_FS_22050;114 break;115 case 24000:116 val |= IEC958_AES3_CON_FS_24000;117 break;118 case 32000:119 val |= IEC958_AES3_CON_FS_32000;120 break;121 case 44100:122 val |= IEC958_AES3_CON_FS_44100;123 break;124 case 48000:125 val |= IEC958_AES3_CON_FS_48000;126 break;127 case 88200:128 val |= IEC958_AES3_CON_FS_88200;129 break;130 case 96000:131 val |= IEC958_AES3_CON_FS_96000;132 break;133 case 176400:134 val |= IEC958_AES3_CON_FS_176400;135 break;136 case 192000:137 val |= IEC958_AES3_CON_FS_192000;138 break;139 default:140 dev_err(component->dev, "unsupported sampling rate\n");141 return -EINVAL;142 }143 144 ret = regmap_write(ak4104->regmap, AK4104_REG_CHN_STATUS(3), val);145 if (ret < 0)146 return ret;147 148 return 0;149}150 151static const struct snd_soc_dai_ops ak4101_dai_ops = {152 .hw_params = ak4104_hw_params,153 .set_fmt = ak4104_set_dai_fmt,154};155 156static struct snd_soc_dai_driver ak4104_dai = {157 .name = "ak4104-hifi",158 .playback = {159 .stream_name = "Playback",160 .channels_min = 2,161 .channels_max = 2,162 .rates = SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |163 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |164 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |165 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,166 .formats = SNDRV_PCM_FMTBIT_S16_LE |167 SNDRV_PCM_FMTBIT_S24_3LE |168 SNDRV_PCM_FMTBIT_S24_LE169 },170 .ops = &ak4101_dai_ops,171};172 173static int ak4104_probe(struct snd_soc_component *component)174{175 struct ak4104_private *ak4104 = snd_soc_component_get_drvdata(component);176 int ret;177 178 ret = regulator_enable(ak4104->regulator);179 if (ret < 0) {180 dev_err(component->dev, "Unable to enable regulator: %d\n", ret);181 return ret;182 }183 184 /* set power-up and non-reset bits */185 ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1,186 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN,187 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN);188 if (ret < 0)189 goto exit_disable_regulator;190 191 /* enable transmitter */192 ret = regmap_update_bits(ak4104->regmap, AK4104_REG_TX,193 AK4104_TX_TXE, AK4104_TX_TXE);194 if (ret < 0)195 goto exit_disable_regulator;196 197 return 0;198 199exit_disable_regulator:200 regulator_disable(ak4104->regulator);201 return ret;202}203 204static void ak4104_remove(struct snd_soc_component *component)205{206 struct ak4104_private *ak4104 = snd_soc_component_get_drvdata(component);207 208 regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1,209 AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0);210 regulator_disable(ak4104->regulator);211}212 213#ifdef CONFIG_PM214static int ak4104_soc_suspend(struct snd_soc_component *component)215{216 struct ak4104_private *priv = snd_soc_component_get_drvdata(component);217 218 regulator_disable(priv->regulator);219 220 return 0;221}222 223static int ak4104_soc_resume(struct snd_soc_component *component)224{225 struct ak4104_private *priv = snd_soc_component_get_drvdata(component);226 int ret;227 228 ret = regulator_enable(priv->regulator);229 if (ret < 0)230 return ret;231 232 return 0;233}234#else235#define ak4104_soc_suspend NULL236#define ak4104_soc_resume NULL237#endif /* CONFIG_PM */238 239static const struct snd_soc_component_driver soc_component_device_ak4104 = {240 .probe = ak4104_probe,241 .remove = ak4104_remove,242 .suspend = ak4104_soc_suspend,243 .resume = ak4104_soc_resume,244 .dapm_widgets = ak4104_dapm_widgets,245 .num_dapm_widgets = ARRAY_SIZE(ak4104_dapm_widgets),246 .dapm_routes = ak4104_dapm_routes,247 .num_dapm_routes = ARRAY_SIZE(ak4104_dapm_routes),248 .idle_bias_on = 1,249 .use_pmdown_time = 1,250 .endianness = 1,251};252 253static const struct regmap_config ak4104_regmap = {254 .reg_bits = 8,255 .val_bits = 8,256 257 .max_register = AK4104_NUM_REGS - 1,258 .read_flag_mask = AK4104_READ,259 .write_flag_mask = AK4104_WRITE,260 261 .cache_type = REGCACHE_RBTREE,262};263 264static int ak4104_spi_probe(struct spi_device *spi)265{266 struct ak4104_private *ak4104;267 struct gpio_desc *reset_gpiod;268 unsigned int val;269 int ret;270 271 spi->bits_per_word = 8;272 spi->mode = SPI_MODE_0;273 ret = spi_setup(spi);274 if (ret < 0)275 return ret;276 277 ak4104 = devm_kzalloc(&spi->dev, sizeof(struct ak4104_private),278 GFP_KERNEL);279 if (ak4104 == NULL)280 return -ENOMEM;281 282 ak4104->regulator = devm_regulator_get(&spi->dev, "vdd");283 if (IS_ERR(ak4104->regulator)) {284 ret = PTR_ERR(ak4104->regulator);285 dev_err(&spi->dev, "Unable to get Vdd regulator: %d\n", ret);286 return ret;287 }288 289 ak4104->regmap = devm_regmap_init_spi(spi, &ak4104_regmap);290 if (IS_ERR(ak4104->regmap)) {291 ret = PTR_ERR(ak4104->regmap);292 return ret;293 }294 295 reset_gpiod = devm_gpiod_get_optional(&spi->dev, "reset",296 GPIOD_OUT_HIGH);297 if (PTR_ERR(reset_gpiod) == -EPROBE_DEFER)298 return -EPROBE_DEFER;299 300 /* read the 'reserved' register - according to the datasheet, it301 * should contain 0x5b. Not a good way to verify the presence of302 * the device, but there is no hardware ID register. */303 ret = regmap_read(ak4104->regmap, AK4104_REG_RESERVED, &val);304 if (ret != 0)305 return ret;306 if (val != AK4104_RESERVED_VAL)307 return -ENODEV;308 309 spi_set_drvdata(spi, ak4104);310 311 ret = devm_snd_soc_register_component(&spi->dev,312 &soc_component_device_ak4104, &ak4104_dai, 1);313 return ret;314}315 316static const struct of_device_id ak4104_of_match[] = {317 { .compatible = "asahi-kasei,ak4104", },318 { }319};320MODULE_DEVICE_TABLE(of, ak4104_of_match);321 322static const struct spi_device_id ak4104_id_table[] = {323 { "ak4104", 0 },324 { }325};326MODULE_DEVICE_TABLE(spi, ak4104_id_table);327 328static struct spi_driver ak4104_spi_driver = {329 .driver = {330 .name = "ak4104",331 .of_match_table = ak4104_of_match,332 },333 .id_table = ak4104_id_table,334 .probe = ak4104_spi_probe,335};336 337module_spi_driver(ak4104_spi_driver);338 339MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");340MODULE_DESCRIPTION("Asahi Kasei AK4104 ALSA SoC driver");341MODULE_LICENSE("GPL");342 343