Path: blob/master/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c
29268 views
// SPDX-License-Identifier: GPL-2.01//2// TAS2781 HDA I2C driver3//4// Copyright 2023 - 2025 Texas Instruments, Inc.5//6// Author: Shenghao Ding <[email protected]>7// Current maintainer: Baojun Xu <[email protected]>89#include <linux/unaligned.h>10#include <linux/acpi.h>11#include <linux/crc8.h>12#include <linux/crc32.h>13#include <linux/efi.h>14#include <linux/firmware.h>15#include <linux/i2c.h>16#include <linux/mod_devicetable.h>17#include <linux/module.h>18#include <linux/pci_ids.h>19#include <linux/pm_runtime.h>20#include <linux/regmap.h>21#include <sound/hda_codec.h>22#include <sound/soc.h>23#include <sound/tas2781.h>24#include <sound/tas2781-comlib-i2c.h>25#include <sound/tlv.h>26#include <sound/tas2770-tlv.h>27#include <sound/tas2781-tlv.h>28#include <sound/tas5825-tlv.h>2930#include "hda_local.h"31#include "hda_auto_parser.h"32#include "hda_component.h"33#include "hda_jack.h"34#include "../generic.h"35#include "tas2781_hda.h"3637#define TAS2563_CAL_VAR_NAME_MAX 1638#define TAS2563_CAL_ARRAY_SIZE 8039#define TAS2563_CAL_DATA_SIZE 440#define TAS2563_MAX_CHANNELS 441#define TAS2563_CAL_CH_SIZE 204243#define TAS2563_CAL_R0_LOW TASDEVICE_REG(0, 0x0f, 0x48)44#define TAS2563_CAL_POWER TASDEVICE_REG(0, 0x0d, 0x3c)45#define TAS2563_CAL_INVR0 TASDEVICE_REG(0, 0x0f, 0x40)46#define TAS2563_CAL_TLIM TASDEVICE_REG(0, 0x10, 0x14)47#define TAS2563_CAL_R0 TASDEVICE_REG(0, 0x0f, 0x34)4849enum device_chip_id {50HDA_TAS2563,51HDA_TAS2770,52HDA_TAS2781,53HDA_TAS5825,54HDA_OTHERS55};5657struct tas2781_hda_i2c_priv {58struct snd_kcontrol *snd_ctls[2];59int (*save_calibration)(struct tas2781_hda *h);6061int hda_chip_id;62};6364static int tas2781_get_i2c_res(struct acpi_resource *ares, void *data)65{66struct tasdevice_priv *tas_priv = data;67struct acpi_resource_i2c_serialbus *sb;6869if (i2c_acpi_get_i2c_resource(ares, &sb)) {70if (tas_priv->ndev < TASDEVICE_MAX_CHANNELS &&71sb->slave_address != tas_priv->global_addr) {72tas_priv->tasdevice[tas_priv->ndev].dev_addr =73(unsigned int)sb->slave_address;74tas_priv->ndev++;75}76}77return 1;78}7980static const struct acpi_gpio_params speakerid_gpios = { 0, 0, false };8182static const struct acpi_gpio_mapping tas2781_speaker_id_gpios[] = {83{ "speakerid-gpios", &speakerid_gpios, 1 },84{ }85};8687static int tas2781_read_acpi(struct tasdevice_priv *p, const char *hid)88{89struct acpi_device *adev;90struct device *physdev;91LIST_HEAD(resources);92const char *sub;93uint32_t subid;94int ret;9596adev = acpi_dev_get_first_match_dev(hid, NULL, -1);97if (!adev) {98dev_err(p->dev,99"Failed to find an ACPI device for %s\n", hid);100return -ENODEV;101}102103physdev = get_device(acpi_get_first_physical_node(adev));104ret = acpi_dev_get_resources(adev, &resources, tas2781_get_i2c_res, p);105if (ret < 0) {106dev_err(p->dev, "Failed to get ACPI resource.\n");107goto err;108}109sub = acpi_get_subsystem_id(ACPI_HANDLE(physdev));110if (IS_ERR(sub)) {111/* No subsys id in older tas2563 projects. */112if (!strncmp(hid, "INT8866", sizeof("INT8866")))113goto end_2563;114dev_err(p->dev, "Failed to get SUBSYS ID.\n");115ret = PTR_ERR(sub);116goto err;117}118/* Speaker id was needed for ASUS projects. */119ret = kstrtou32(sub, 16, &subid);120if (!ret && upper_16_bits(subid) == PCI_VENDOR_ID_ASUSTEK) {121ret = devm_acpi_dev_add_driver_gpios(p->dev,122tas2781_speaker_id_gpios);123if (ret < 0)124dev_err(p->dev, "Failed to add driver gpio %d.\n",125ret);126p->speaker_id = devm_gpiod_get(p->dev, "speakerid", GPIOD_IN);127if (IS_ERR(p->speaker_id)) {128dev_err(p->dev, "Failed to get Speaker id.\n");129ret = PTR_ERR(p->speaker_id);130goto err;131}132} else {133p->speaker_id = NULL;134}135136end_2563:137acpi_dev_free_resource_list(&resources);138strscpy(p->dev_name, hid, sizeof(p->dev_name));139put_device(physdev);140acpi_dev_put(adev);141142return 0;143144err:145dev_err(p->dev, "read acpi error, ret: %d\n", ret);146put_device(physdev);147acpi_dev_put(adev);148149return ret;150}151152static void tas2781_hda_playback_hook(struct device *dev, int action)153{154struct tas2781_hda *tas_hda = dev_get_drvdata(dev);155156dev_dbg(tas_hda->dev, "%s: action = %d\n", __func__, action);157switch (action) {158case HDA_GEN_PCM_ACT_OPEN:159pm_runtime_get_sync(dev);160scoped_guard(mutex, &tas_hda->priv->codec_lock) {161tasdevice_tuning_switch(tas_hda->priv, 0);162tas_hda->priv->playback_started = true;163}164break;165case HDA_GEN_PCM_ACT_CLOSE:166scoped_guard(mutex, &tas_hda->priv->codec_lock) {167tasdevice_tuning_switch(tas_hda->priv, 1);168tas_hda->priv->playback_started = false;169}170171pm_runtime_put_autosuspend(dev);172break;173default:174break;175}176}177178static int tas2781_amp_getvol(struct snd_kcontrol *kcontrol,179struct snd_ctl_elem_value *ucontrol)180{181struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);182struct soc_mixer_control *mc =183(struct soc_mixer_control *)kcontrol->private_value;184int ret;185186guard(mutex)(&tas_priv->codec_lock);187188ret = tasdevice_amp_getvol(tas_priv, ucontrol, mc);189190dev_dbg(tas_priv->dev, "%s: kcontrol %s: %ld\n",191__func__, kcontrol->id.name, ucontrol->value.integer.value[0]);192193return ret;194}195196static int tas2781_amp_putvol(struct snd_kcontrol *kcontrol,197struct snd_ctl_elem_value *ucontrol)198{199struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);200struct soc_mixer_control *mc =201(struct soc_mixer_control *)kcontrol->private_value;202203guard(mutex)(&tas_priv->codec_lock);204205dev_dbg(tas_priv->dev, "%s: kcontrol %s: -> %ld\n",206__func__, kcontrol->id.name, ucontrol->value.integer.value[0]);207208/* The check of the given value is in tasdevice_amp_putvol. */209return tasdevice_amp_putvol(tas_priv, ucontrol, mc);210}211212static int tas2781_force_fwload_get(struct snd_kcontrol *kcontrol,213struct snd_ctl_elem_value *ucontrol)214{215struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);216217guard(mutex)(&tas_priv->codec_lock);218219ucontrol->value.integer.value[0] = (int)tas_priv->force_fwload_status;220dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d\n",221__func__, kcontrol->id.name, tas_priv->force_fwload_status);222223return 0;224}225226static int tas2781_force_fwload_put(struct snd_kcontrol *kcontrol,227struct snd_ctl_elem_value *ucontrol)228{229struct tasdevice_priv *tas_priv = snd_kcontrol_chip(kcontrol);230bool change, val = (bool)ucontrol->value.integer.value[0];231232guard(mutex)(&tas_priv->codec_lock);233234dev_dbg(tas_priv->dev, "%s: kcontrol %s: %d -> %d\n",235__func__, kcontrol->id.name,236tas_priv->force_fwload_status, val);237238if (tas_priv->force_fwload_status == val)239change = false;240else {241change = true;242tas_priv->force_fwload_status = val;243}244245return change;246}247248static const struct snd_kcontrol_new tas2770_snd_controls[] = {249ACARD_SINGLE_RANGE_EXT_TLV("Speaker Analog Volume", TAS2770_AMP_LEVEL,2500, 0, 20, 0, tas2781_amp_getvol,251tas2781_amp_putvol, tas2770_amp_tlv),252ACARD_SINGLE_RANGE_EXT_TLV("Speaker Digital Volume", TAS2770_DVC_LEVEL,2530, 0, 200, 1, tas2781_amp_getvol,254tas2781_amp_putvol, tas2770_dvc_tlv),255};256257static const struct snd_kcontrol_new tas2781_snd_controls[] = {258ACARD_SINGLE_RANGE_EXT_TLV("Speaker Analog Volume", TAS2781_AMP_LEVEL,2591, 0, 20, 0, tas2781_amp_getvol,260tas2781_amp_putvol, tas2781_amp_tlv),261ACARD_SINGLE_BOOL_EXT("Speaker Force Firmware Load", 0,262tas2781_force_fwload_get, tas2781_force_fwload_put),263};264265static const struct snd_kcontrol_new tas5825_snd_controls[] = {266ACARD_SINGLE_RANGE_EXT_TLV("Speaker Analog Volume", TAS5825_AMP_LEVEL,2670, 0, 31, 1, tas2781_amp_getvol,268tas2781_amp_putvol, tas5825_amp_tlv),269ACARD_SINGLE_RANGE_EXT_TLV("Speaker Digital Volume", TAS5825_DVC_LEVEL,2700, 0, 254, 1, tas2781_amp_getvol,271tas2781_amp_putvol, tas5825_dvc_tlv),272ACARD_SINGLE_BOOL_EXT("Speaker Force Firmware Load", 0,273tas2781_force_fwload_get, tas2781_force_fwload_put),274};275276static const struct snd_kcontrol_new tasdevice_prof_ctrl = {277.name = "Speaker Profile Id",278.iface = SNDRV_CTL_ELEM_IFACE_CARD,279.info = tasdevice_info_profile,280.get = tasdevice_get_profile_id,281.put = tasdevice_set_profile_id,282};283284static const struct snd_kcontrol_new tasdevice_dsp_prog_ctrl = {285.name = "Speaker Program Id",286.iface = SNDRV_CTL_ELEM_IFACE_CARD,287.info = tasdevice_info_programs,288.get = tasdevice_program_get,289.put = tasdevice_program_put,290};291292static const struct snd_kcontrol_new tasdevice_dsp_conf_ctrl = {293.name = "Speaker Config Id",294.iface = SNDRV_CTL_ELEM_IFACE_CARD,295.info = tasdevice_info_config,296.get = tasdevice_config_get,297.put = tasdevice_config_put,298};299300static int tas2563_save_calibration(struct tas2781_hda *h)301{302efi_guid_t efi_guid = tasdev_fct_efi_guid[LENOVO];303char *vars[TASDEV_CALIB_N] = {304"R0_%d", "R0_Low_%d", "InvR0_%d", "Power_%d", "TLim_%d"305};306efi_char16_t efi_name[TAS2563_CAL_VAR_NAME_MAX];307unsigned long max_size = TAS2563_CAL_DATA_SIZE;308unsigned char var8[TAS2563_CAL_VAR_NAME_MAX];309struct tasdevice_priv *p = h->priv;310struct calidata *cd = &p->cali_data;311struct cali_reg *r = &cd->cali_reg_array;312unsigned int offset = 0;313unsigned char *data;314__be32 bedata;315efi_status_t status;316unsigned int attr;317int ret, i, j, k;318319if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) {320dev_err(p->dev, "%s: NO EFI FOUND!\n", __func__);321return -EINVAL;322}323324cd->cali_dat_sz_per_dev = TAS2563_CAL_DATA_SIZE * TASDEV_CALIB_N;325326/* extra byte for each device is the device number */327cd->total_sz = (cd->cali_dat_sz_per_dev + 1) * p->ndev;328data = cd->data = devm_kzalloc(p->dev, cd->total_sz,329GFP_KERNEL);330if (!data)331return -ENOMEM;332333for (i = 0; i < p->ndev; ++i) {334data[offset] = i;335offset++;336for (j = 0; j < TASDEV_CALIB_N; ++j) {337/* EFI name for calibration started with 1, not 0 */338ret = snprintf(var8, sizeof(var8), vars[j], i + 1);339if (ret < 0 || ret >= sizeof(var8) - 1) {340dev_err(p->dev, "%s: Read %s failed\n",341__func__, var8);342return -EINVAL;343}344/*345* Our variable names are ASCII by construction, but346* EFI names are wide chars. Convert and zero-pad.347*/348memset(efi_name, 0, sizeof(efi_name));349for (k = 0; k < sizeof(var8) && var8[k]; k++)350efi_name[k] = var8[k];351status = efi.get_variable(efi_name,352&efi_guid, &attr, &max_size,353&data[offset]);354if (status != EFI_SUCCESS ||355max_size != TAS2563_CAL_DATA_SIZE) {356dev_warn(p->dev,357"Dev %d: Caldat[%d] read failed %ld\n",358i, j, status);359return -EINVAL;360}361bedata = cpu_to_be32(*(uint32_t *)&data[offset]);362memcpy(&data[offset], &bedata, sizeof(bedata));363offset += TAS2563_CAL_DATA_SIZE;364}365}366367if (cd->total_sz != offset) {368dev_err(p->dev, "%s: tot_size(%lu) and offset(%u) mismatch\n",369__func__, cd->total_sz, offset);370return -EINVAL;371}372373r->r0_reg = TAS2563_CAL_R0;374r->invr0_reg = TAS2563_CAL_INVR0;375r->r0_low_reg = TAS2563_CAL_R0_LOW;376r->pow_reg = TAS2563_CAL_POWER;377r->tlimit_reg = TAS2563_CAL_TLIM;378379/*380* TAS2781_FMWLIB supports two solutions of calibrated data. One is381* from the driver itself: driver reads the calibrated files directly382* during probe; The other from user space: during init of audio hal,383* the audio hal will pass the calibrated data via kcontrol interface.384* Driver will store this data in "struct calidata" for use. For hda385* device, calibrated data are usunally saved into UEFI. So Hda side386* codec driver use the mixture of these two solutions, driver reads387* the data from UEFI, then store this data in "struct calidata" for388* use.389*/390p->is_user_space_calidata = true;391392return 0;393}394395static void tas2781_hda_remove_controls(struct tas2781_hda *tas_hda)396{397struct tas2781_hda_i2c_priv *hda_priv = tas_hda->hda_priv;398struct hda_codec *codec = tas_hda->priv->codec;399400snd_ctl_remove(codec->card, tas_hda->dsp_prog_ctl);401snd_ctl_remove(codec->card, tas_hda->dsp_conf_ctl);402403for (int i = ARRAY_SIZE(hda_priv->snd_ctls) - 1; i >= 0; i--)404snd_ctl_remove(codec->card, hda_priv->snd_ctls[i]);405406snd_ctl_remove(codec->card, tas_hda->prof_ctl);407}408409static void tasdev_add_kcontrols(struct tasdevice_priv *tas_priv,410struct snd_kcontrol **ctls, struct hda_codec *codec,411const struct snd_kcontrol_new *tas_snd_ctrls, int num_ctls)412{413int i, ret;414415for (i = 0; i < num_ctls; i++) {416ctls[i] = snd_ctl_new1(417&tas_snd_ctrls[i], tas_priv);418ret = snd_ctl_add(codec->card, ctls[i]);419if (ret) {420dev_err(tas_priv->dev,421"Failed to add KControl %s = %d\n",422tas_snd_ctrls[i].name, ret);423break;424}425}426}427428static void tasdevice_dspfw_init(void *context)429{430struct tasdevice_priv *tas_priv = context;431struct tas2781_hda *tas_hda = dev_get_drvdata(tas_priv->dev);432struct tas2781_hda_i2c_priv *hda_priv = tas_hda->hda_priv;433struct hda_codec *codec = tas_priv->codec;434int ret, spk_id;435436tasdevice_dsp_remove(tas_priv);437tas_priv->fw_state = TASDEVICE_DSP_FW_PENDING;438if (tas_priv->speaker_id != NULL) {439// Speaker id need to be checked for ASUS only.440spk_id = gpiod_get_value(tas_priv->speaker_id);441if (spk_id < 0) {442// Speaker id is not valid, use default.443dev_dbg(tas_priv->dev, "Wrong spk_id = %d\n", spk_id);444spk_id = 0;445}446snprintf(tas_priv->coef_binaryname,447sizeof(tas_priv->coef_binaryname),448"TAS2XXX%04X%d.bin",449lower_16_bits(codec->core.subsystem_id),450spk_id);451} else {452snprintf(tas_priv->coef_binaryname,453sizeof(tas_priv->coef_binaryname),454"TAS2XXX%04X.bin",455lower_16_bits(codec->core.subsystem_id));456}457ret = tasdevice_dsp_parser(tas_priv);458if (ret) {459dev_err(tas_priv->dev, "dspfw load %s error\n",460tas_priv->coef_binaryname);461tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;462return;463}464tasdev_add_kcontrols(tas_priv, &tas_hda->dsp_prog_ctl, codec,465&tasdevice_dsp_prog_ctrl, 1);466tasdev_add_kcontrols(tas_priv, &tas_hda->dsp_conf_ctl, codec,467&tasdevice_dsp_conf_ctrl, 1);468469tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK;470tasdevice_prmg_load(tas_priv, 0);471if (tas_priv->fmw->nr_programs > 0)472tas_priv->cur_prog = 0;473if (tas_priv->fmw->nr_configurations > 0)474tas_priv->cur_conf = 0;475476/* If calibrated data occurs error, dsp will still works with default477* calibrated data inside algo.478*/479hda_priv->save_calibration(tas_hda);480}481482static void tasdev_fw_ready(const struct firmware *fmw, void *context)483{484struct tasdevice_priv *tas_priv = context;485struct tas2781_hda *tas_hda = dev_get_drvdata(tas_priv->dev);486struct tas2781_hda_i2c_priv *hda_priv = tas_hda->hda_priv;487struct hda_codec *codec = tas_priv->codec;488int ret;489490pm_runtime_get_sync(tas_priv->dev);491mutex_lock(&tas_priv->codec_lock);492493ret = tasdevice_rca_parser(tas_priv, fmw);494if (ret)495goto out;496497tas_priv->fw_state = TASDEVICE_RCA_FW_OK;498tasdev_add_kcontrols(tas_priv, &tas_hda->prof_ctl, codec,499&tasdevice_prof_ctrl, 1);500501switch (hda_priv->hda_chip_id) {502case HDA_TAS2770:503tasdev_add_kcontrols(tas_priv, hda_priv->snd_ctls, codec,504&tas2770_snd_controls[0],505ARRAY_SIZE(tas2770_snd_controls));506break;507case HDA_TAS2781:508tasdev_add_kcontrols(tas_priv, hda_priv->snd_ctls, codec,509&tas2781_snd_controls[0],510ARRAY_SIZE(tas2781_snd_controls));511tasdevice_dspfw_init(context);512break;513case HDA_TAS5825:514tasdev_add_kcontrols(tas_priv, hda_priv->snd_ctls, codec,515&tas5825_snd_controls[0],516ARRAY_SIZE(tas5825_snd_controls));517tasdevice_dspfw_init(context);518break;519case HDA_TAS2563:520tasdevice_dspfw_init(context);521break;522default:523break;524}525526out:527mutex_unlock(&tas_hda->priv->codec_lock);528release_firmware(fmw);529pm_runtime_put_autosuspend(tas_hda->dev);530}531532static int tas2781_hda_bind(struct device *dev, struct device *master,533void *master_data)534{535struct tas2781_hda *tas_hda = dev_get_drvdata(dev);536struct hda_component_parent *parent = master_data;537struct hda_component *comp;538struct hda_codec *codec;539unsigned int subid;540int ret;541542comp = hda_component_from_index(parent, tas_hda->priv->index);543if (!comp)544return -EINVAL;545546if (comp->dev)547return -EBUSY;548549codec = parent->codec;550subid = codec->core.subsystem_id >> 16;551552switch (subid) {553case 0x1028:554tas_hda->catlog_id = DELL;555break;556default:557tas_hda->catlog_id = LENOVO;558break;559}560561pm_runtime_get_sync(dev);562563comp->dev = dev;564565strscpy(comp->name, dev_name(dev), sizeof(comp->name));566567ret = tascodec_init(tas_hda->priv, codec, THIS_MODULE, tasdev_fw_ready);568if (!ret)569comp->playback_hook = tas2781_hda_playback_hook;570571pm_runtime_put_autosuspend(dev);572573return ret;574}575576static void tas2781_hda_unbind(struct device *dev,577struct device *master, void *master_data)578{579struct tas2781_hda *tas_hda = dev_get_drvdata(dev);580struct hda_component_parent *parent = master_data;581struct hda_component *comp;582583comp = hda_component_from_index(parent, tas_hda->priv->index);584if (comp && (comp->dev == dev)) {585comp->dev = NULL;586memset(comp->name, 0, sizeof(comp->name));587comp->playback_hook = NULL;588}589590tas2781_hda_remove_controls(tas_hda);591592tasdevice_config_info_remove(tas_hda->priv);593tasdevice_dsp_remove(tas_hda->priv);594595tas_hda->priv->fw_state = TASDEVICE_DSP_FW_PENDING;596}597598static const struct component_ops tas2781_hda_comp_ops = {599.bind = tas2781_hda_bind,600.unbind = tas2781_hda_unbind,601};602603static int tas2781_hda_i2c_probe(struct i2c_client *clt)604{605struct tas2781_hda_i2c_priv *hda_priv;606struct tas2781_hda *tas_hda;607const char *device_name;608int ret;609610tas_hda = devm_kzalloc(&clt->dev, sizeof(*tas_hda), GFP_KERNEL);611if (!tas_hda)612return -ENOMEM;613614hda_priv = devm_kzalloc(&clt->dev, sizeof(*hda_priv), GFP_KERNEL);615if (!hda_priv)616return -ENOMEM;617618tas_hda->hda_priv = hda_priv;619620dev_set_drvdata(&clt->dev, tas_hda);621tas_hda->dev = &clt->dev;622623tas_hda->priv = tasdevice_kzalloc(clt);624if (!tas_hda->priv)625return -ENOMEM;626627if (strstr(dev_name(&clt->dev), "TIAS2781")) {628/*629* TAS2781, integrated on-chip DSP with630* global I2C address supported.631*/632device_name = "TIAS2781";633hda_priv->hda_chip_id = HDA_TAS2781;634hda_priv->save_calibration = tas2781_save_calibration;635tas_hda->priv->global_addr = TAS2781_GLOBAL_ADDR;636} else if (strstarts(dev_name(&clt->dev), "i2c-TXNW2770")) {637/*638* TAS2770, has no on-chip DSP, so no calibration data639* required; has no global I2C address supported.640*/641device_name = "TXNW2770";642hda_priv->hda_chip_id = HDA_TAS2770;643} else if (strstarts(dev_name(&clt->dev),644"i2c-TXNW2781:00-tas2781-hda.0")) {645device_name = "TXNW2781";646hda_priv->hda_chip_id = HDA_TAS2781;647hda_priv->save_calibration = tas2781_save_calibration;648tas_hda->priv->global_addr = TAS2781_GLOBAL_ADDR;649} else if (strstr(dev_name(&clt->dev), "INT8866")) {650/*651* TAS2563, integrated on-chip DSP with652* global I2C address supported.653*/654device_name = "INT8866";655hda_priv->hda_chip_id = HDA_TAS2563;656hda_priv->save_calibration = tas2563_save_calibration;657tas_hda->priv->global_addr = TAS2563_GLOBAL_ADDR;658} else if (strstarts(dev_name(&clt->dev), "i2c-TXNW5825")) {659/*660* TAS5825, integrated on-chip DSP without661* global I2C address and calibration supported.662*/663device_name = "TXNW5825";664hda_priv->hda_chip_id = HDA_TAS5825;665} else {666return -ENODEV;667}668669tas_hda->priv->irq = clt->irq;670ret = tas2781_read_acpi(tas_hda->priv, device_name);671if (ret)672return dev_err_probe(tas_hda->dev, ret,673"Platform not supported\n");674675ret = tasdevice_init(tas_hda->priv);676if (ret)677goto err;678679pm_runtime_set_autosuspend_delay(tas_hda->dev, 3000);680pm_runtime_use_autosuspend(tas_hda->dev);681pm_runtime_mark_last_busy(tas_hda->dev);682pm_runtime_set_active(tas_hda->dev);683pm_runtime_enable(tas_hda->dev);684685tasdevice_reset(tas_hda->priv);686687ret = component_add(tas_hda->dev, &tas2781_hda_comp_ops);688if (ret) {689dev_err(tas_hda->dev, "Register component failed: %d\n", ret);690pm_runtime_disable(tas_hda->dev);691}692693err:694if (ret)695tas2781_hda_remove(&clt->dev, &tas2781_hda_comp_ops);696return ret;697}698699static void tas2781_hda_i2c_remove(struct i2c_client *clt)700{701tas2781_hda_remove(&clt->dev, &tas2781_hda_comp_ops);702}703704static int tas2781_runtime_suspend(struct device *dev)705{706struct tas2781_hda *tas_hda = dev_get_drvdata(dev);707708dev_dbg(tas_hda->dev, "Runtime Suspend\n");709710guard(mutex)(&tas_hda->priv->codec_lock);711712/* The driver powers up the amplifiers at module load time.713* Stop the playback if it's unused.714*/715if (tas_hda->priv->playback_started) {716tasdevice_tuning_switch(tas_hda->priv, 1);717tas_hda->priv->playback_started = false;718}719720return 0;721}722723static int tas2781_runtime_resume(struct device *dev)724{725struct tas2781_hda *tas_hda = dev_get_drvdata(dev);726727dev_dbg(tas_hda->dev, "Runtime Resume\n");728729guard(mutex)(&tas_hda->priv->codec_lock);730731tasdevice_prmg_load(tas_hda->priv, tas_hda->priv->cur_prog);732733return 0;734}735736static int tas2781_system_suspend(struct device *dev)737{738struct tas2781_hda *tas_hda = dev_get_drvdata(dev);739740dev_dbg(tas_hda->priv->dev, "System Suspend\n");741742guard(mutex)(&tas_hda->priv->codec_lock);743744/* Shutdown chip before system suspend */745if (tas_hda->priv->playback_started)746tasdevice_tuning_switch(tas_hda->priv, 1);747748/*749* Reset GPIO may be shared, so cannot reset here.750* However beyond this point, amps may be powered down.751*/752return 0;753}754755static int tas2781_system_resume(struct device *dev)756{757struct tas2781_hda *tas_hda = dev_get_drvdata(dev);758int i;759760dev_dbg(tas_hda->priv->dev, "System Resume\n");761762guard(mutex)(&tas_hda->priv->codec_lock);763764for (i = 0; i < tas_hda->priv->ndev; i++) {765tas_hda->priv->tasdevice[i].cur_book = -1;766tas_hda->priv->tasdevice[i].cur_prog = -1;767tas_hda->priv->tasdevice[i].cur_conf = -1;768}769tasdevice_reset(tas_hda->priv);770tasdevice_prmg_load(tas_hda->priv, tas_hda->priv->cur_prog);771772if (tas_hda->priv->playback_started)773tasdevice_tuning_switch(tas_hda->priv, 0);774775return 0;776}777778static const struct dev_pm_ops tas2781_hda_pm_ops = {779RUNTIME_PM_OPS(tas2781_runtime_suspend, tas2781_runtime_resume, NULL)780SYSTEM_SLEEP_PM_OPS(tas2781_system_suspend, tas2781_system_resume)781};782783static const struct i2c_device_id tas2781_hda_i2c_id[] = {784{ "tas2781-hda" },785{}786};787788static const struct acpi_device_id tas2781_acpi_hda_match[] = {789{"INT8866", 0 },790{"TIAS2781", 0 },791{"TXNW2770", 0 },792{"TXNW2781", 0 },793{"TXNW5825", 0 },794{}795};796MODULE_DEVICE_TABLE(acpi, tas2781_acpi_hda_match);797798static struct i2c_driver tas2781_hda_i2c_driver = {799.driver = {800.name = "tas2781-hda",801.acpi_match_table = tas2781_acpi_hda_match,802.pm = &tas2781_hda_pm_ops,803},804.id_table = tas2781_hda_i2c_id,805.probe = tas2781_hda_i2c_probe,806.remove = tas2781_hda_i2c_remove,807};808module_i2c_driver(tas2781_hda_i2c_driver);809810MODULE_DESCRIPTION("TAS2781 HDA Driver");811MODULE_AUTHOR("Shenghao Ding, TI, <[email protected]>");812MODULE_LICENSE("GPL");813MODULE_IMPORT_NS("SND_SOC_TAS2781_FMWLIB");814MODULE_IMPORT_NS("SND_HDA_SCODEC_TAS2781");815816817