2424#include <sound/tas2781.h>
2525#include <sound/tas2781-comlib-i2c.h>
2626#include <sound/tlv.h>
27+ #include <sound/tas2770-tlv.h>
2728#include <sound/tas2781-tlv.h>
2829
2930#include "hda_local.h"
4546#define TAS2563_CAL_TLIM TASDEVICE_REG(0, 0x10, 0x14)
4647#define TAS2563_CAL_R0 TASDEVICE_REG(0, 0x0f, 0x34)
4748
49+ enum device_chip_id {
50+ HDA_TAS2563 ,
51+ HDA_TAS2770 ,
52+ HDA_TAS2781 ,
53+ HDA_OTHERS
54+ };
55+
4856struct tas2781_hda_i2c_priv {
4957 struct snd_kcontrol * snd_ctls [2 ];
5058 int (* save_calibration )(struct tas2781_hda * h );
59+
60+ int hda_chip_id ;
5161};
5262
5363static int tas2781_get_i2c_res (struct acpi_resource * ares , void * data )
@@ -245,6 +255,15 @@ static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol,
245255 return change ;
246256}
247257
258+ static const struct snd_kcontrol_new tas2770_snd_controls [] = {
259+ ACARD_SINGLE_RANGE_EXT_TLV ("Speaker Analog Volume" , TAS2770_AMP_LEVEL ,
260+ 0 , 0 , 20 , 0 , tas2781_amp_getvol ,
261+ tas2781_amp_putvol , tas2770_amp_tlv ),
262+ ACARD_SINGLE_RANGE_EXT_TLV ("Speaker Digital Volume" , TAS2770_DVC_LEVEL ,
263+ 0 , 0 , 31 , 0 , tas2781_amp_getvol ,
264+ tas2781_amp_putvol , tas2770_dvc_tlv ),
265+ };
266+
248267static const struct snd_kcontrol_new tas2781_snd_controls [] = {
249268 ACARD_SINGLE_RANGE_EXT_TLV ("Speaker Analog Gain" , TAS2781_AMP_LEVEL ,
250269 1 , 0 , 20 , 0 , tas2781_amp_getvol ,
@@ -253,23 +272,23 @@ static const struct snd_kcontrol_new tas2781_snd_controls[] = {
253272 tas2781_force_fwload_get , tas2781_force_fwload_put ),
254273};
255274
256- static const struct snd_kcontrol_new tas2781_prof_ctrl = {
275+ static const struct snd_kcontrol_new tasdevice_prof_ctrl = {
257276 .name = "Speaker Profile Id" ,
258277 .iface = SNDRV_CTL_ELEM_IFACE_CARD ,
259278 .info = tasdevice_info_profile ,
260279 .get = tasdevice_get_profile_id ,
261280 .put = tasdevice_set_profile_id ,
262281};
263282
264- static const struct snd_kcontrol_new tas2781_dsp_prog_ctrl = {
283+ static const struct snd_kcontrol_new tasdevice_dsp_prog_ctrl = {
265284 .name = "Speaker Program Id" ,
266285 .iface = SNDRV_CTL_ELEM_IFACE_CARD ,
267286 .info = tasdevice_info_programs ,
268287 .get = tasdevice_program_get ,
269288 .put = tasdevice_program_put ,
270289};
271290
272- static const struct snd_kcontrol_new tas2781_dsp_conf_ctrl = {
291+ static const struct snd_kcontrol_new tasdevice_dsp_conf_ctrl = {
273292 .name = "Speaker Config Id" ,
274293 .iface = SNDRV_CTL_ELEM_IFACE_CARD ,
275294 .info = tasdevice_info_config ,
@@ -378,44 +397,34 @@ static void tas2781_hda_remove_controls(struct tas2781_hda *tas_hda)
378397 snd_ctl_remove (codec -> card , tas_hda -> prof_ctl );
379398}
380399
381- static void tasdev_fw_ready (const struct firmware * fmw , void * context )
400+ static void tasdev_add_kcontrols (struct tasdevice_priv * tas_priv ,
401+ struct snd_kcontrol * * ctls , struct hda_codec * codec ,
402+ const struct snd_kcontrol_new * tas_snd_ctrls , int num_ctls )
382403{
383- struct tasdevice_priv * tas_priv = context ;
384- struct tas2781_hda * tas_hda = dev_get_drvdata (tas_priv -> dev );
385- struct tas2781_hda_i2c_priv * hda_priv = tas_hda -> hda_priv ;
386- struct hda_codec * codec = tas_priv -> codec ;
387- int i , ret , spk_id ;
388-
389- pm_runtime_get_sync (tas_priv -> dev );
390- mutex_lock (& tas_priv -> codec_lock );
404+ int i , ret ;
391405
392- ret = tasdevice_rca_parser (tas_priv , fmw );
393- if (ret )
394- goto out ;
395-
396- tas_hda -> prof_ctl = snd_ctl_new1 (& tas2781_prof_ctrl , tas_priv );
397- ret = snd_ctl_add (codec -> card , tas_hda -> prof_ctl );
398- if (ret ) {
399- dev_err (tas_priv -> dev ,
400- "Failed to add KControl %s = %d\n" ,
401- tas2781_prof_ctrl .name , ret );
402- goto out ;
403- }
404-
405- for (i = 0 ; i < ARRAY_SIZE (tas2781_snd_controls ); i ++ ) {
406- hda_priv -> snd_ctls [i ] = snd_ctl_new1 (& tas2781_snd_controls [i ],
407- tas_priv );
408- ret = snd_ctl_add (codec -> card , hda_priv -> snd_ctls [i ]);
406+ for (i = 0 ; i < num_ctls ; i ++ ) {
407+ ctls [i ] = snd_ctl_new1 (
408+ & tas_snd_ctrls [i ], tas_priv );
409+ ret = snd_ctl_add (codec -> card , ctls [i ]);
409410 if (ret ) {
410411 dev_err (tas_priv -> dev ,
411412 "Failed to add KControl %s = %d\n" ,
412- tas2781_snd_controls [i ].name , ret );
413- goto out ;
413+ tas_snd_ctrls [i ].name , ret );
414+ break ;
414415 }
415416 }
417+ }
416418
417- tasdevice_dsp_remove (tas_priv );
419+ static void tasdevice_dspfw_init (void * context )
420+ {
421+ struct tasdevice_priv * tas_priv = context ;
422+ struct tas2781_hda * tas_hda = dev_get_drvdata (tas_priv -> dev );
423+ struct tas2781_hda_i2c_priv * hda_priv = tas_hda -> hda_priv ;
424+ struct hda_codec * codec = tas_priv -> codec ;
425+ int ret , spk_id ;
418426
427+ tasdevice_dsp_remove (tas_priv );
419428 tas_priv -> fw_state = TASDEVICE_DSP_FW_PENDING ;
420429 if (tas_priv -> speaker_id != NULL ) {
421430 // Speaker id need to be checked for ASUS only.
@@ -441,28 +450,12 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context)
441450 dev_err (tas_priv -> dev , "dspfw load %s error\n" ,
442451 tas_priv -> coef_binaryname );
443452 tas_priv -> fw_state = TASDEVICE_DSP_FW_FAIL ;
444- goto out ;
445- }
446-
447- tas_hda -> dsp_prog_ctl = snd_ctl_new1 (& tas2781_dsp_prog_ctrl ,
448- tas_priv );
449- ret = snd_ctl_add (codec -> card , tas_hda -> dsp_prog_ctl );
450- if (ret ) {
451- dev_err (tas_priv -> dev ,
452- "Failed to add KControl %s = %d\n" ,
453- tas2781_dsp_prog_ctrl .name , ret );
454- goto out ;
455- }
456-
457- tas_hda -> dsp_conf_ctl = snd_ctl_new1 (& tas2781_dsp_conf_ctrl ,
458- tas_priv );
459- ret = snd_ctl_add (codec -> card , tas_hda -> dsp_conf_ctl );
460- if (ret ) {
461- dev_err (tas_priv -> dev ,
462- "Failed to add KControl %s = %d\n" ,
463- tas2781_dsp_conf_ctrl .name , ret );
464- goto out ;
453+ return ;
465454 }
455+ tasdev_add_kcontrols (tas_priv , & tas_hda -> dsp_prog_ctl , codec ,
456+ & tasdevice_dsp_prog_ctrl , 1 );
457+ tasdev_add_kcontrols (tas_priv , & tas_hda -> dsp_conf_ctl , codec ,
458+ & tasdevice_dsp_conf_ctrl , 1 );
466459
467460 tas_priv -> fw_state = TASDEVICE_DSP_FW_ALL_OK ;
468461 tasdevice_prmg_load (tas_priv , 0 );
@@ -475,9 +468,45 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context)
475468 * calibrated data inside algo.
476469 */
477470 hda_priv -> save_calibration (tas_hda );
471+ }
472+
473+ static void tasdev_fw_ready (const struct firmware * fmw , void * context )
474+ {
475+ struct tasdevice_priv * tas_priv = context ;
476+ struct tas2781_hda * tas_hda = dev_get_drvdata (tas_priv -> dev );
477+ struct tas2781_hda_i2c_priv * hda_priv = tas_hda -> hda_priv ;
478+ struct hda_codec * codec = tas_priv -> codec ;
479+ int ret ;
480+
481+ pm_runtime_get_sync (tas_priv -> dev );
482+ mutex_lock (& tas_priv -> codec_lock );
483+
484+ ret = tasdevice_rca_parser (tas_priv , fmw );
485+ if (ret )
486+ goto out ;
478487
479- tasdevice_tuning_switch (tas_hda -> priv , 0 );
480- tas_hda -> priv -> playback_started = true;
488+ tas_priv -> fw_state = TASDEVICE_RCA_FW_OK ;
489+ tasdev_add_kcontrols (tas_priv , & tas_hda -> prof_ctl , codec ,
490+ & tasdevice_prof_ctrl , 1 );
491+
492+ switch (hda_priv -> hda_chip_id ) {
493+ case HDA_TAS2770 :
494+ tasdev_add_kcontrols (tas_priv , hda_priv -> snd_ctls , codec ,
495+ & tas2770_snd_controls [0 ],
496+ ARRAY_SIZE (tas2770_snd_controls ));
497+ break ;
498+ case HDA_TAS2781 :
499+ tasdev_add_kcontrols (tas_priv , hda_priv -> snd_ctls , codec ,
500+ & tas2781_snd_controls [0 ],
501+ ARRAY_SIZE (tas2781_snd_controls ));
502+ tasdevice_dspfw_init (context );
503+ break ;
504+ case HDA_TAS2563 :
505+ tasdevice_dspfw_init (context );
506+ break ;
507+ default :
508+ break ;
509+ }
481510
482511out :
483512 mutex_unlock (& tas_hda -> priv -> codec_lock );
@@ -581,16 +610,33 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt)
581610 return - ENOMEM ;
582611
583612 if (strstr (dev_name (& clt -> dev ), "TIAS2781" )) {
613+ /*
614+ * TAS2781, integrated on-chip DSP with
615+ * global I2C address supported.
616+ */
584617 device_name = "TIAS2781" ;
618+ hda_priv -> hda_chip_id = HDA_TAS2781 ;
585619 hda_priv -> save_calibration = tas2781_save_calibration ;
586620 tas_hda -> priv -> global_addr = TAS2781_GLOBAL_ADDR ;
621+ } else if (strstarts (dev_name (& clt -> dev ), "i2c-TXNW2770" )) {
622+ /*
623+ * TAS2770, has no on-chip DSP, so no calibration data
624+ * required; has no global I2C address supported.
625+ */
626+ device_name = "TXNW2770" ;
627+ hda_priv -> hda_chip_id = HDA_TAS2770 ;
587628 } else if (strstarts (dev_name (& clt -> dev ),
588629 "i2c-TXNW2781:00-tas2781-hda.0" )) {
589630 device_name = "TXNW2781" ;
590631 hda_priv -> save_calibration = tas2781_save_calibration ;
591632 tas_hda -> priv -> global_addr = TAS2781_GLOBAL_ADDR ;
592633 } else if (strstr (dev_name (& clt -> dev ), "INT8866" )) {
634+ /*
635+ * TAS2563, integrated on-chip DSP with
636+ * global I2C address supported.
637+ */
593638 device_name = "INT8866" ;
639+ hda_priv -> hda_chip_id = HDA_TAS2563 ;
594640 hda_priv -> save_calibration = tas2563_save_calibration ;
595641 tas_hda -> priv -> global_addr = TAS2563_GLOBAL_ADDR ;
596642 } else {
@@ -727,6 +773,7 @@ static const struct i2c_device_id tas2781_hda_i2c_id[] = {
727773static const struct acpi_device_id tas2781_acpi_hda_match [] = {
728774 {"INT8866" , 0 },
729775 {"TIAS2781" , 0 },
776+ {"TXNW2770" , 0 },
730777 {"TXNW2781" , 0 },
731778 {}
732779};
0 commit comments