1 // SPDX-License-Identifier: GPL-2.0 2 // Driver for the Texas Instruments TAS2780 Mono 3 // Audio amplifier 4 // Copyright (C) 2022 Texas Instruments Inc. 5 6 #include <linux/module.h> 7 #include <linux/err.h> 8 #include <linux/pm.h> 9 #include <linux/i2c.h> 10 #include <linux/gpio.h> 11 #include <linux/gpio/consumer.h> 12 #include <linux/regmap.h> 13 #include <linux/of.h> 14 #include <sound/soc.h> 15 #include <sound/pcm.h> 16 #include <sound/pcm_params.h> 17 #include <sound/tlv.h> 18 19 #include "tas2780.h" 20 21 struct tas2780_priv { 22 struct snd_soc_component *component; 23 struct gpio_desc *reset_gpio; 24 struct regmap *regmap; 25 struct device *dev; 26 int v_sense_slot; 27 int i_sense_slot; 28 }; 29 30 static void tas2780_reset(struct tas2780_priv *tas2780) 31 { 32 int ret = 0; 33 34 if (tas2780->reset_gpio) { 35 gpiod_set_value_cansleep(tas2780->reset_gpio, 0); 36 usleep_range(2000, 2050); 37 gpiod_set_value_cansleep(tas2780->reset_gpio, 1); 38 usleep_range(2000, 2050); 39 } 40 41 ret = snd_soc_component_write(tas2780->component, TAS2780_SW_RST, 42 TAS2780_RST); 43 if (ret) 44 dev_err(tas2780->dev, "%s:errCode:0x%x Reset error!\n", 45 __func__, ret); 46 } 47 48 #ifdef CONFIG_PM 49 static int tas2780_codec_suspend(struct snd_soc_component *component) 50 { 51 struct tas2780_priv *tas2780 = 52 snd_soc_component_get_drvdata(component); 53 int ret = 0; 54 55 ret = snd_soc_component_update_bits(component, TAS2780_PWR_CTRL, 56 TAS2780_PWR_CTRL_MASK, TAS2780_PWR_CTRL_SHUTDOWN); 57 if (ret < 0) { 58 dev_err(tas2780->dev, "%s:errCode:0x%0x:power down error\n", 59 __func__, ret); 60 goto err; 61 } 62 ret = 0; 63 regcache_cache_only(tas2780->regmap, true); 64 regcache_mark_dirty(tas2780->regmap); 65 err: 66 return ret; 67 } 68 69 static int tas2780_codec_resume(struct snd_soc_component *component) 70 { 71 struct tas2780_priv *tas2780 = 72 snd_soc_component_get_drvdata(component); 73 int ret; 74 75 ret = snd_soc_component_update_bits(component, TAS2780_PWR_CTRL, 76 TAS2780_PWR_CTRL_MASK, TAS2780_PWR_CTRL_ACTIVE); 77 78 if (ret < 0) { 79 dev_err(tas2780->dev, "%s:errCode:0x%0x:power down error\n", 80 __func__, ret); 81 goto err; 82 } 83 regcache_cache_only(tas2780->regmap, false); 84 ret = regcache_sync(tas2780->regmap); 85 err: 86 return ret; 87 } 88 #endif 89 90 static const char * const tas2780_ASI1_src[] = { 91 "I2C offset", "Left", "Right", "LeftRightDiv2", 92 }; 93 94 static SOC_ENUM_SINGLE_DECL( 95 tas2780_ASI1_src_enum, TAS2780_TDM_CFG2, 4, tas2780_ASI1_src); 96 97 static const struct snd_kcontrol_new tas2780_asi1_mux = 98 SOC_DAPM_ENUM("ASI1 Source", tas2780_ASI1_src_enum); 99 100 static const struct snd_kcontrol_new isense_switch = 101 SOC_DAPM_SINGLE("Switch", TAS2780_PWR_CTRL, 102 TAS2780_ISENSE_POWER_EN, 1, 1); 103 static const struct snd_kcontrol_new vsense_switch = 104 SOC_DAPM_SINGLE("Switch", TAS2780_PWR_CTRL, 105 TAS2780_VSENSE_POWER_EN, 1, 1); 106 107 static const struct snd_soc_dapm_widget tas2780_dapm_widgets[] = { 108 SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0), 109 SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2780_asi1_mux), 110 SND_SOC_DAPM_SWITCH("ISENSE", TAS2780_PWR_CTRL, 111 TAS2780_ISENSE_POWER_EN, 1, &isense_switch), 112 SND_SOC_DAPM_SWITCH("VSENSE", TAS2780_PWR_CTRL, 113 TAS2780_VSENSE_POWER_EN, 1, &vsense_switch), 114 SND_SOC_DAPM_OUTPUT("OUT"), 115 SND_SOC_DAPM_SIGGEN("VMON"), 116 SND_SOC_DAPM_SIGGEN("IMON") 117 }; 118 119 static const struct snd_soc_dapm_route tas2780_audio_map[] = { 120 {"ASI1 Sel", "I2C offset", "ASI1"}, 121 {"ASI1 Sel", "Left", "ASI1"}, 122 {"ASI1 Sel", "Right", "ASI1"}, 123 {"ASI1 Sel", "LeftRightDiv2", "ASI1"}, 124 {"OUT", NULL, "ASI1 Sel"}, 125 {"ISENSE", "Switch", "IMON"}, 126 {"VSENSE", "Switch", "VMON"}, 127 }; 128 129 static int tas2780_mute(struct snd_soc_dai *dai, int mute, int direction) 130 { 131 struct snd_soc_component *component = dai->component; 132 struct tas2780_priv *tas2780 = 133 snd_soc_component_get_drvdata(component); 134 int ret = 0; 135 136 ret = snd_soc_component_update_bits(component, TAS2780_PWR_CTRL, 137 TAS2780_PWR_CTRL_MASK, 138 mute ? TAS2780_PWR_CTRL_MUTE : 0); 139 if (ret < 0) { 140 dev_err(tas2780->dev, "%s: Failed to set powercontrol\n", 141 __func__); 142 goto err; 143 } 144 ret = 0; 145 err: 146 return ret; 147 } 148 149 static int tas2780_set_bitwidth(struct tas2780_priv *tas2780, int bitwidth) 150 { 151 struct snd_soc_component *component = tas2780->component; 152 int sense_en; 153 int val; 154 int ret; 155 int slot_size; 156 157 switch (bitwidth) { 158 case SNDRV_PCM_FORMAT_S16_LE: 159 ret = snd_soc_component_update_bits(component, 160 TAS2780_TDM_CFG2, 161 TAS2780_TDM_CFG2_RXW_MASK, 162 TAS2780_TDM_CFG2_RXW_16BITS); 163 slot_size = TAS2780_TDM_CFG2_RXS_16BITS; 164 break; 165 case SNDRV_PCM_FORMAT_S24_LE: 166 ret = snd_soc_component_update_bits(component, 167 TAS2780_TDM_CFG2, 168 TAS2780_TDM_CFG2_RXW_MASK, 169 TAS2780_TDM_CFG2_RXW_24BITS); 170 slot_size = TAS2780_TDM_CFG2_RXS_24BITS; 171 break; 172 case SNDRV_PCM_FORMAT_S32_LE: 173 ret = snd_soc_component_update_bits(component, 174 TAS2780_TDM_CFG2, 175 TAS2780_TDM_CFG2_RXW_MASK, 176 TAS2780_TDM_CFG2_RXW_32BITS); 177 slot_size = TAS2780_TDM_CFG2_RXS_32BITS; 178 break; 179 180 default: 181 ret = -EINVAL; 182 } 183 184 if (ret < 0) { 185 dev_err(tas2780->dev, "%s:errCode:0x%x set bitwidth error\n", 186 __func__, ret); 187 goto err; 188 } 189 190 ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG2, 191 TAS2780_TDM_CFG2_RXS_MASK, slot_size); 192 if (ret < 0) { 193 dev_err(tas2780->dev, 194 "%s:errCode:0x%x set RX slot size error\n", 195 __func__, ret); 196 goto err; 197 } 198 199 val = snd_soc_component_read(tas2780->component, TAS2780_PWR_CTRL); 200 if (val < 0) { 201 dev_err(tas2780->dev, "%s:errCode:0x%x read PWR_CTRL error\n", 202 __func__, val); 203 ret = val; 204 goto err; 205 } 206 207 if (val & (1 << TAS2780_VSENSE_POWER_EN)) 208 sense_en = 0; 209 else 210 sense_en = TAS2780_TDM_CFG5_VSNS_ENABLE; 211 212 ret = snd_soc_component_update_bits(tas2780->component, 213 TAS2780_TDM_CFG5, TAS2780_TDM_CFG5_VSNS_ENABLE, sense_en); 214 if (ret < 0) { 215 dev_err(tas2780->dev, "%s:errCode:0x%x enable vSNS error\n", 216 __func__, ret); 217 goto err; 218 } 219 220 if (val & (1 << TAS2780_ISENSE_POWER_EN)) 221 sense_en = 0; 222 else 223 sense_en = TAS2780_TDM_CFG6_ISNS_ENABLE; 224 225 ret = snd_soc_component_update_bits(tas2780->component, 226 TAS2780_TDM_CFG6, TAS2780_TDM_CFG6_ISNS_ENABLE, sense_en); 227 if (ret < 0) { 228 dev_err(tas2780->dev, "%s:errCode:0x%x enable iSNS error\n", 229 __func__, ret); 230 goto err; 231 } 232 ret = 0; 233 err: 234 return ret; 235 } 236 237 static int tas2780_set_samplerate( 238 struct tas2780_priv *tas2780, int samplerate) 239 { 240 struct snd_soc_component *component = tas2780->component; 241 int ramp_rate_val; 242 int ret; 243 244 switch (samplerate) { 245 case 48000: 246 ramp_rate_val = TAS2780_TDM_CFG0_SMP_48KHZ | 247 TAS2780_TDM_CFG0_44_1_48KHZ; 248 break; 249 case 44100: 250 ramp_rate_val = TAS2780_TDM_CFG0_SMP_44_1KHZ | 251 TAS2780_TDM_CFG0_44_1_48KHZ; 252 break; 253 case 96000: 254 ramp_rate_val = TAS2780_TDM_CFG0_SMP_48KHZ | 255 TAS2780_TDM_CFG0_88_2_96KHZ; 256 break; 257 case 88200: 258 ramp_rate_val = TAS2780_TDM_CFG0_SMP_44_1KHZ | 259 TAS2780_TDM_CFG0_88_2_96KHZ; 260 break; 261 default: 262 return -EINVAL; 263 } 264 ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG0, 265 TAS2780_TDM_CFG0_SMP_MASK | TAS2780_TDM_CFG0_MASK, 266 ramp_rate_val); 267 if (ret < 0) { 268 dev_err(tas2780->dev, 269 "%s:errCode:0x%x Failed to set ramp_rate_val\n", 270 __func__, ret); 271 goto err; 272 } 273 ret = 0; 274 err: 275 return ret; 276 } 277 278 static int tas2780_hw_params(struct snd_pcm_substream *substream, 279 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 280 { 281 struct snd_soc_component *component = dai->component; 282 struct tas2780_priv *tas2780 = 283 snd_soc_component_get_drvdata(component); 284 int ret; 285 286 ret = tas2780_set_bitwidth(tas2780, params_format(params)); 287 if (ret < 0) 288 return ret; 289 290 return tas2780_set_samplerate(tas2780, params_rate(params)); 291 } 292 293 static int tas2780_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 294 { 295 struct snd_soc_component *component = dai->component; 296 struct tas2780_priv *tas2780 = 297 snd_soc_component_get_drvdata(component); 298 u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0; 299 int iface; 300 int ret = 0; 301 302 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 303 case SND_SOC_DAIFMT_NB_NF: 304 asi_cfg_1 = TAS2780_TDM_CFG1_RX_RISING; 305 break; 306 case SND_SOC_DAIFMT_IB_NF: 307 asi_cfg_1 = TAS2780_TDM_CFG1_RX_FALLING; 308 break; 309 default: 310 dev_err(tas2780->dev, "ASI format Inverse is not found\n"); 311 return -EINVAL; 312 } 313 314 ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG1, 315 TAS2780_TDM_CFG1_RX_MASK, asi_cfg_1); 316 if (ret < 0) { 317 dev_err(tas2780->dev, 318 "%s:errCode:0x%x Failed to set asi_cfg_1\n", 319 __func__, ret); 320 goto err; 321 } 322 323 if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S) 324 || ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) 325 == SND_SOC_DAIFMT_DSP_A)){ 326 iface = TAS2780_TDM_CFG2_SCFG_I2S; 327 tdm_rx_start_slot = 1; 328 } else { 329 if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) 330 == SND_SOC_DAIFMT_DSP_B) 331 || ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) 332 == SND_SOC_DAIFMT_LEFT_J)) { 333 iface = TAS2780_TDM_CFG2_SCFG_LEFT_J; 334 tdm_rx_start_slot = 0; 335 } else { 336 dev_err(tas2780->dev, 337 "%s:DAI Format is not found, fmt=0x%x\n", 338 __func__, fmt); 339 ret = -EINVAL; 340 goto err; 341 } 342 } 343 ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG1, 344 TAS2780_TDM_CFG1_MASK, 345 (tdm_rx_start_slot << TAS2780_TDM_CFG1_51_SHIFT)); 346 if (ret < 0) { 347 dev_err(tas2780->dev, 348 "%s:errCode:0x%x Failed to set tdm_rx_start_slot\n", 349 __func__, ret); 350 goto err; 351 } 352 353 ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG2, 354 TAS2780_TDM_CFG2_SCFG_MASK, iface); 355 if (ret < 0) { 356 dev_err(tas2780->dev, "%s:errCode:0x%x Failed to set iface\n", 357 __func__, ret); 358 goto err; 359 } 360 ret = 0; 361 err: 362 return ret; 363 } 364 365 static int tas2780_set_dai_tdm_slot(struct snd_soc_dai *dai, 366 unsigned int tx_mask, 367 unsigned int rx_mask, 368 int slots, int slot_width) 369 { 370 struct snd_soc_component *component = dai->component; 371 struct tas2780_priv *tas2780 = 372 snd_soc_component_get_drvdata(component); 373 int left_slot, right_slot; 374 int slots_cfg; 375 int slot_size; 376 int ret = 0; 377 378 if (tx_mask == 0 || rx_mask != 0) 379 return -EINVAL; 380 381 left_slot = __ffs(tx_mask); 382 tx_mask &= ~(1 << left_slot); 383 if (tx_mask == 0) { 384 right_slot = left_slot; 385 } else { 386 right_slot = __ffs(tx_mask); 387 tx_mask &= ~(1 << right_slot); 388 } 389 390 if (tx_mask != 0 || left_slot >= slots || right_slot >= slots) 391 return -EINVAL; 392 393 slots_cfg = (right_slot << TAS2780_TDM_CFG3_RXS_SHIFT) | left_slot; 394 ret = snd_soc_component_write(component, TAS2780_TDM_CFG3, slots_cfg); 395 if (ret) { 396 dev_err(tas2780->dev, 397 "%s:errCode:0x%x Failed to set slots_cfg\n", 398 __func__, ret); 399 goto err; 400 } 401 402 switch (slot_width) { 403 case 16: 404 slot_size = TAS2780_TDM_CFG2_RXS_16BITS; 405 break; 406 case 24: 407 slot_size = TAS2780_TDM_CFG2_RXS_24BITS; 408 break; 409 case 32: 410 slot_size = TAS2780_TDM_CFG2_RXS_32BITS; 411 break; 412 default: 413 ret = -EINVAL; 414 goto err; 415 } 416 417 ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG2, 418 TAS2780_TDM_CFG2_RXS_MASK, slot_size); 419 if (ret < 0) { 420 dev_err(tas2780->dev, 421 "%s:errCode:0x%x Failed to set slot_size\n", 422 __func__, ret); 423 goto err; 424 } 425 426 ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG5, 427 TAS2780_TDM_CFG5_50_MASK, tas2780->v_sense_slot); 428 if (ret < 0) { 429 dev_err(tas2780->dev, 430 "%s:errCode:0x%x Failed to set v_sense_slot\n", 431 __func__, ret); 432 goto err; 433 } 434 435 ret = snd_soc_component_update_bits(component, TAS2780_TDM_CFG6, 436 TAS2780_TDM_CFG6_50_MASK, tas2780->i_sense_slot); 437 if (ret < 0) { 438 dev_err(tas2780->dev, 439 "%s:errCode:0x%x Failed to set i_sense_slot\n", 440 __func__, ret); 441 goto err; 442 } 443 ret = 0; 444 err: 445 return ret; 446 } 447 448 static const struct snd_soc_dai_ops tas2780_dai_ops = { 449 .mute_stream = tas2780_mute, 450 .hw_params = tas2780_hw_params, 451 .set_fmt = tas2780_set_fmt, 452 .set_tdm_slot = tas2780_set_dai_tdm_slot, 453 .no_capture_mute = 1, 454 }; 455 456 #define TAS2780_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 457 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 458 459 #define TAS2780_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ 460 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_88200) 461 462 static struct snd_soc_dai_driver tas2780_dai_driver[] = { 463 { 464 .name = "tas2780 ASI1", 465 .id = 0, 466 .playback = { 467 .stream_name = "ASI1 Playback", 468 .channels_min = 2, 469 .channels_max = 2, 470 .rates = TAS2780_RATES, 471 .formats = TAS2780_FORMATS, 472 }, 473 .capture = { 474 .stream_name = "ASI1 Capture", 475 .channels_min = 1, 476 .channels_max = 2, 477 .rates = TAS2780_RATES, 478 .formats = TAS2780_FORMATS, 479 }, 480 .ops = &tas2780_dai_ops, 481 .symmetric_rate = 1, 482 }, 483 }; 484 485 static int tas2780_codec_probe(struct snd_soc_component *component) 486 { 487 struct tas2780_priv *tas2780 = 488 snd_soc_component_get_drvdata(component); 489 int ret = 0; 490 491 tas2780->component = component; 492 493 tas2780_reset(tas2780); 494 ret = snd_soc_component_update_bits(component, 495 TAS2780_IC_CFG, TAS2780_IC_CFG_MASK, 496 TAS2780_IC_CFG_ENABLE); 497 if (ret < 0) 498 dev_err(tas2780->dev, "%s:errCode:0x%0x\n", 499 __func__, ret); 500 501 return ret; 502 } 503 504 static DECLARE_TLV_DB_SCALE(tas2780_digital_tlv, 1100, 50, 0); 505 static DECLARE_TLV_DB_SCALE(tas2780_playback_volume, -10000, 50, 0); 506 507 static const struct snd_kcontrol_new tas2780_snd_controls[] = { 508 SOC_SINGLE_TLV("Speaker Volume", TAS2780_DVC, 0, 509 TAS2780_DVC_MAX, 1, tas2780_playback_volume), 510 SOC_SINGLE_TLV("Amp Gain Volume", TAS2780_CHNL_0, 0, 0x14, 0, 511 tas2780_digital_tlv), 512 }; 513 514 static const struct snd_soc_component_driver soc_component_driver_tas2780 = { 515 .probe = tas2780_codec_probe, 516 #ifdef CONFIG_PM 517 .suspend = tas2780_codec_suspend, 518 .resume = tas2780_codec_resume, 519 #endif 520 .controls = tas2780_snd_controls, 521 .num_controls = ARRAY_SIZE(tas2780_snd_controls), 522 .dapm_widgets = tas2780_dapm_widgets, 523 .num_dapm_widgets = ARRAY_SIZE(tas2780_dapm_widgets), 524 .dapm_routes = tas2780_audio_map, 525 .num_dapm_routes = ARRAY_SIZE(tas2780_audio_map), 526 .idle_bias_on = 1, 527 .endianness = 1, 528 }; 529 530 static const struct reg_default tas2780_reg_defaults[] = { 531 { TAS2780_PAGE, 0x00 }, 532 { TAS2780_SW_RST, 0x00 }, 533 { TAS2780_PWR_CTRL, 0x1a }, 534 { TAS2780_DVC, 0x00 }, 535 { TAS2780_CHNL_0, 0x00 }, 536 { TAS2780_TDM_CFG0, 0x09 }, 537 { TAS2780_TDM_CFG1, 0x02 }, 538 { TAS2780_TDM_CFG2, 0x0a }, 539 { TAS2780_TDM_CFG3, 0x10 }, 540 { TAS2780_TDM_CFG5, 0x42 }, 541 }; 542 543 static const struct regmap_range_cfg tas2780_regmap_ranges[] = { 544 { 545 .range_min = 0, 546 .range_max = 1 * 128, 547 .selector_reg = TAS2780_PAGE, 548 .selector_mask = 0xff, 549 .selector_shift = 0, 550 .window_start = 0, 551 .window_len = 128, 552 }, 553 }; 554 555 static const struct regmap_config tas2780_i2c_regmap = { 556 .reg_bits = 8, 557 .val_bits = 8, 558 .reg_defaults = tas2780_reg_defaults, 559 .num_reg_defaults = ARRAY_SIZE(tas2780_reg_defaults), 560 .cache_type = REGCACHE_RBTREE, 561 .ranges = tas2780_regmap_ranges, 562 .num_ranges = ARRAY_SIZE(tas2780_regmap_ranges), 563 .max_register = 1 * 128, 564 }; 565 566 static int tas2780_parse_dt(struct device *dev, struct tas2780_priv *tas2780) 567 { 568 int ret = 0; 569 570 tas2780->reset_gpio = devm_gpiod_get_optional(tas2780->dev, "reset", 571 GPIOD_OUT_HIGH); 572 if (IS_ERR(tas2780->reset_gpio)) { 573 if (PTR_ERR(tas2780->reset_gpio) == -EPROBE_DEFER) { 574 tas2780->reset_gpio = NULL; 575 return -EPROBE_DEFER; 576 } 577 } 578 579 ret = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no", 580 &tas2780->i_sense_slot); 581 if (ret) 582 tas2780->i_sense_slot = 0; 583 584 ret = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no", 585 &tas2780->v_sense_slot); 586 if (ret) 587 tas2780->v_sense_slot = 2; 588 589 return 0; 590 } 591 592 static int tas2780_i2c_probe(struct i2c_client *client) 593 { 594 struct tas2780_priv *tas2780; 595 int result; 596 597 tas2780 = devm_kzalloc(&client->dev, sizeof(struct tas2780_priv), 598 GFP_KERNEL); 599 if (!tas2780) 600 return -ENOMEM; 601 tas2780->dev = &client->dev; 602 i2c_set_clientdata(client, tas2780); 603 dev_set_drvdata(&client->dev, tas2780); 604 605 tas2780->regmap = devm_regmap_init_i2c(client, &tas2780_i2c_regmap); 606 if (IS_ERR(tas2780->regmap)) { 607 result = PTR_ERR(tas2780->regmap); 608 dev_err(&client->dev, "Failed to allocate register map: %d\n", 609 result); 610 return result; 611 } 612 613 if (client->dev.of_node) { 614 result = tas2780_parse_dt(&client->dev, tas2780); 615 if (result) { 616 dev_err(tas2780->dev, 617 "%s: Failed to parse devicetree\n", __func__); 618 return result; 619 } 620 } 621 622 return devm_snd_soc_register_component(tas2780->dev, 623 &soc_component_driver_tas2780, tas2780_dai_driver, 624 ARRAY_SIZE(tas2780_dai_driver)); 625 } 626 627 static const struct i2c_device_id tas2780_i2c_id[] = { 628 { "tas2780"}, 629 { } 630 }; 631 MODULE_DEVICE_TABLE(i2c, tas2780_i2c_id); 632 633 #if defined(CONFIG_OF) 634 static const struct of_device_id tas2780_of_match[] = { 635 { .compatible = "ti,tas2780" }, 636 {}, 637 }; 638 MODULE_DEVICE_TABLE(of, tas2780_of_match); 639 #endif 640 641 static struct i2c_driver tas2780_i2c_driver = { 642 .driver = { 643 .name = "tas2780", 644 .of_match_table = of_match_ptr(tas2780_of_match), 645 }, 646 .probe = tas2780_i2c_probe, 647 .id_table = tas2780_i2c_id, 648 }; 649 module_i2c_driver(tas2780_i2c_driver); 650 651 MODULE_AUTHOR("Raphael Xu <raphael-xu@ti.com>"); 652 MODULE_DESCRIPTION("TAS2780 I2C Smart Amplifier driver"); 653 MODULE_LICENSE("GPL"); 654
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.