Commit graph

19 commits

Author SHA1 Message Date
Gergo Koteles
dcaca1b5f0 ALSA: hda/tas2781: annotate calibration data endianness
Sparse reports an endian mismatch.
The amplifier expects the calibration data as big-endian.
Use the __be32 type to express endianness better.

Fixes: c3ca4458cc ("ALSA: hda/tas2781: add TAS2563 support for 14ARB7")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202401072137.Oc7pQgRW-lkp@intel.com/

Signed-off-by: Gergo Koteles <soyer@irl.hu>
Link: https://lore.kernel.org/r/3852ff28ea7d5d8f2086d8dd78aeff8d1d984991.1704748435.git.soyer@irl.hu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2024-01-09 15:13:09 +01:00
Gergo Koteles
c3ca4458cc ALSA: hda/tas2781: add TAS2563 support for 14ARB7
The INT8866 belongs to the Lenovo Yoga 7 Gen 7 AMD 14ARB7
laptop. It has two TAS2563 amplifier. Add the PNP ID
and calibration functions to handle them.

ACPI excerpt:

Scope (_SB.I2CD)
{
    Device (TAS)
    {
        Name (_HID, "INT8866")  // _HID: Hardware ID
        Name (_UID, Zero)  // _UID: Unique ID
        Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
        {
            Name (RBUF, ResourceTemplate ()
            {
                I2cSerialBusV2 (0x004C, ControllerInitiated, 0x00061A80,
                    AddressingMode7Bit, "\\_SB.I2CD",
                    0x00, ResourceConsumer, , Exclusive,
                    )
                I2cSerialBusV2 (0x004D, ControllerInitiated, 0x00061A80,
                    AddressingMode7Bit, "\\_SB.I2CD",
                    0x00, ResourceConsumer, , Exclusive,
                    )
                GpioInt (Edge, ActiveLow, SharedAndWake, PullNone, 0x0000,
                    "\\_SB.GPIO", 0x00, ResourceConsumer, ,
                    )
                    {   // Pin list
                        0x0020
                    }
             })
             Return (RBUF) /* \_SB_.I2CD.TAS_._CRS.RBUF */
        }

        Method (_STA, 0, NotSerialized)  // _STA: Status
        {
            Return (0x0F)
        }
    }
}

Signed-off-by: Gergo Koteles <soyer@irl.hu>
Link: https://lore.kernel.org/r/3b8d4c602e1a46922f53bc9afc8b705d55aa4872.1703891777.git.soyer@irl.hu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2024-01-02 16:15:28 +01:00
Gergo Koteles
c021ca729f ALSA: hda/tas2781: add configurable global i2c address
Make the global i2c address configurable to support compatible amplifiers
with different global i2c address.

Signed-off-by: Gergo Koteles <soyer@irl.hu>
Link: https://lore.kernel.org/r/a252f1efeed5049f027f01e699c9e10e1e05bf9e.1703891777.git.soyer@irl.hu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2024-01-02 16:15:09 +01:00
Gergo Koteles
76f5f55c45 ALSA: hda/tas2781: add ptrs to calibration functions
Make calibration functions configurable to support different calibration
data storage modes.

Signed-off-by: Gergo Koteles <soyer@irl.hu>
Link: https://lore.kernel.org/r/5859c77ffef752b8a9784713b412d815d7e2688c.1703891777.git.soyer@irl.hu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2024-01-02 16:14:01 +01:00
Gergo Koteles
68f7f3ff6c ALSA: hda/tas2781: configure the amp after firmware load
Make the amp available immediately after a module
load to avoid having to wait for a PCM hook action.
(eg. unloading & loading the module while listening
music)

Signed-off-by: Gergo Koteles <soyer@irl.hu>
Link: https://lore.kernel.org/r/7f2f65d9212aa16edd4db8725489ae59dbe74c66.1703895108.git.soyer@irl.hu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-12-30 10:50:55 +01:00
Gergo Koteles
4e7914eb1d ALSA: hda/tas2781: remove sound controls in unbind
Remove sound controls in hda_unbind to make
module loadable after module unload.

Add a driver specific struct (tas2781_hda) to store
the controls.

This patch depends on patch:
ALSA: hda/tas2781: do not use regcache

Fixes: 5be27f1e3e ("ALSA: hda/tas2781: Add tas2781 HDA driver")
CC: stable@vger.kernel.org
Signed-off-by: Gergo Koteles <soyer@irl.hu>
Link: https://lore.kernel.org/r/362aa3e2f81b9259a3e5222f576bec5debfc5e88.1703204848.git.soyer@irl.hu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-12-29 13:42:24 +01:00
Gergo Koteles
e7aa105657 ALSA: hda/tas2781: move set_drv_data outside tasdevice_init
allow driver specific driver data in tas2781-hda-i2c and tas2781-i2c

Fixes: ef3bcde75d ("ASoC: tas2781: Add tas2781 driver")
CC: stable@vger.kernel.org
Signed-off-by: Gergo Koteles <soyer@irl.hu>
Link: https://lore.kernel.org/r/1398bd8bf3e935b1595a99128320e4a1913e210a.1703204848.git.soyer@irl.hu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-12-29 13:42:17 +01:00
Gergo Koteles
a0c9f7f2e0 ALSA: hda/tas2781: fix typos in comment
Correct typos.

Signed-off-by: Gergo Koteles <soyer@irl.hu>
Link: https://lore.kernel.org/r/ead5609d63e71e8e87c13e1767decca5b272d696.1703203812.git.soyer@irl.hu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-12-29 13:41:31 +01:00
Gergo Koteles
6dad45f4d2 ALSA: hda/tas2781: do not use regcache
There are two problems with using regcache in this module.

The amplifier has 3 addressing levels (BOOK, PAGE, REG). The firmware
contains blocks that must be written to BOOK 0x8C. The regcache doesn't
know anything about BOOK, so regcache_sync writes invalid values to the
actual BOOK.

The module handles 2 or more separate amplifiers. The amplifiers have
different register values, and the module uses only one regmap/regcache
for all the amplifiers. The regcache_sync only writes the last amplifier
used.

The module successfully restores all the written register values (RC
profile, program, configuration, calibration) without regcache.

Remove regcache functions and set regmap cache_type to REGCACHE_NONE.

Link: https://lore.kernel.org/r/21a183b5a08cb23b193af78d4b1114cc59419272.1701906455.git.soyer@irl.hu/

Fixes: 5be27f1e3e ("ALSA: hda/tas2781: Add tas2781 HDA driver")
Acked-by: Mark Brown <broonie@kernel.org>
CC: stable@vger.kernel.org
Signed-off-by: Gergo Koteles <soyer@irl.hu>
Link: https://lore.kernel.org/r/491aeed0e2eecc3b704ec856f815db21bad3ba0e.1703202126.git.soyer@irl.hu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-12-29 13:41:04 +01:00
Gergo Koteles
ec1de5c214 ALSA: hda/tas2781: select program 0, conf 0 by default
Currently, cur_prog/cur_conf remains at the default value (-1), while
program 0 has been loaded into the amplifiers.

In the playback hook, tasdevice_tuning_switch tries to restore the
cur_prog/cur_conf. In the runtime_resume/system_resume,
tasdevice_prmg_load tries to load the cur_prog as well.

Set cur_prog and cur_conf to 0 if available in the firmware.

Fixes: 5be27f1e3e ("ALSA: hda/tas2781: Add tas2781 HDA driver")
CC: stable@vger.kernel.org
Signed-off-by: Gergo Koteles <soyer@irl.hu>
Link: https://lore.kernel.org/r/038add0bdca1f979cc7abcce8f24cbcd3544084b.1702596646.git.soyer@irl.hu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-12-15 08:13:40 +01:00
Gergo Koteles
315deab289 ALSA: hda/tas2781: reset the amp before component_add
Calling component_add starts loading the firmware, the callback function
writes the program to the amplifiers. If the module resets the
amplifiers after component_add, it happens that one of the amplifiers
does not work because the reset and program writing are interleaving.

Call tas2781_reset before component_add to ensure reliable
initialization.

Fixes: 5be27f1e3e ("ALSA: hda/tas2781: Add tas2781 HDA driver")
CC: stable@vger.kernel.org
Signed-off-by: Gergo Koteles <soyer@irl.hu>
Link: https://lore.kernel.org/r/4d23bf58558e23ee8097de01f70f1eb8d9de2d15.1702511246.git.soyer@irl.hu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-12-14 12:04:38 +01:00
Gergo Koteles
6c6fa26414 ALSA: hda/tas2781: call cleanup functions only once
If the module can load the RCA but not the firmware binary, it will call
the cleanup functions. Then unloading the module causes general
protection fault due to double free.

Do not call the cleanup functions in tasdev_fw_ready.

general protection fault, probably for non-canonical address
0x6f2b8a2bff4c8fec: 0000 [#1] PREEMPT SMP NOPTI
Call Trace:
 <TASK>
 ? die_addr+0x36/0x90
 ? exc_general_protection+0x1c5/0x430
 ? asm_exc_general_protection+0x26/0x30
 ? tasdevice_config_info_remove+0x6d/0xd0 [snd_soc_tas2781_fmwlib]
 tas2781_hda_unbind+0xaa/0x100 [snd_hda_scodec_tas2781_i2c]
 component_unbind+0x2e/0x50
 component_unbind_all+0x92/0xa0
 component_del+0xa8/0x140
 tas2781_hda_remove.isra.0+0x32/0x60 [snd_hda_scodec_tas2781_i2c]
 i2c_device_remove+0x26/0xb0

Fixes: 5be27f1e3e ("ALSA: hda/tas2781: Add tas2781 HDA driver")
CC: stable@vger.kernel.org
Signed-off-by: Gergo Koteles <soyer@irl.hu>
Link: https://lore.kernel.org/r/1a0885c424bb21172702d254655882b59ef6477a.1702510018.git.soyer@irl.hu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-12-14 12:03:49 +01:00
Gergo Koteles
3307142271 ALSA: hda/tas2781: handle missing EFI calibration data
The code does not properly check whether the calibration variable is
available in the EFI. If it is not available, it causes a NULL pointer
dereference.

Check the return value of the first get_variable call also.

BUG: kernel NULL pointer dereference, address: 0000000000000000
Call Trace:
 <TASK>
 ? __die+0x23/0x70
 ? page_fault_oops+0x171/0x4e0
 ? srso_alias_return_thunk+0x5/0x7f
 ? schedule+0x5e/0xd0
 ? exc_page_fault+0x7f/0x180
 ? asm_exc_page_fault+0x26/0x30
 ? crc32_body+0x2c/0x120
 ? tas2781_save_calibration+0xe4/0x220 [snd_hda_scodec_tas2781_i2c]
 tasdev_fw_ready+0x1af/0x280 [snd_hda_scodec_tas2781_i2c]
 request_firmware_work_func+0x59/0xa0

Fixes: 5be27f1e3e ("ALSA: hda/tas2781: Add tas2781 HDA driver")
CC: stable@vger.kernel.org
Signed-off-by: Gergo Koteles <soyer@irl.hu>
Link: https://lore.kernel.org/r/f1f6583bda918f78556f67d522ca7b3b91cebbd5.1702251102.git.soyer@irl.hu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-12-11 08:58:18 +01:00
Gergo Koteles
75a25d31b8 ALSA: hda/tas2781: leave hda_component in usable state
Unloading then loading the module causes a NULL ponter dereference.

The hda_unbind zeroes the hda_component, later the hda_bind tries
to dereference the codec field.

The hda_component is only initialized once by tas2781_generic_fixup.

Set only previously modified fields to NULL.

BUG: kernel NULL pointer dereference, address: 0000000000000322
Call Trace:
 <TASK>
 ? __die+0x23/0x70
 ? page_fault_oops+0x171/0x4e0
 ? exc_page_fault+0x7f/0x180
 ? asm_exc_page_fault+0x26/0x30
 ? tas2781_hda_bind+0x59/0x140 [snd_hda_scodec_tas2781_i2c]
 component_bind_all+0xf3/0x240
 try_to_bring_up_aggregate_device+0x1c3/0x270
 __component_add+0xbc/0x1a0
 tas2781_hda_i2c_probe+0x289/0x3a0 [snd_hda_scodec_tas2781_i2c]
 i2c_device_probe+0x136/0x2e0

Fixes: 5be27f1e3e ("ALSA: hda/tas2781: Add tas2781 HDA driver")
Cc: stable@vger.kernel.org
Signed-off-by: Gergo Koteles <soyer@irl.hu>
Link: https://lore.kernel.org/r/8b8ed2bd5f75fbb32e354a3226c2f966fa85b46b.1702156522.git.soyer@irl.hu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-12-10 10:06:31 +01:00
Takashi Iwai
da42bcb30e ALSA: hda/tas2781: Use standard clamp() macro
Instead of the home-made clamp() function, use the standard macro().

Fixes: 5be27f1e3e ("ALSA: hda/tas2781: Add tas2781 HDA driver")
Link: https://lore.kernel.org/r/20230831123620.23064-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-08-31 14:36:46 +02:00
Uwe Kleine-König
ed81cb9e05 ALSA: hda/tas2781: Switch back to use struct i2c_driver's .probe()
struct i2c_driver::probe_new is about to go away. Switch the driver to
use the probe callback with the same prototype.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Fixes: 5be27f1e3e ("ALSA: hda/tas2781: Add tas2781 HDA driver")
Link: https://lore.kernel.org/r/20230824200219.9569-1-u.kleine-koenig@pengutronix.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-08-25 09:45:27 +02:00
Takashi Iwai
17a1eab7b7 ALSA: hda/tas2781: Fix PM refcount unbalance at tas2781_hda_bind()
The error path of tas2781_hda_bind() needs to release PM refcount as
well.  Modify the code flow to handle properly.

Fixes: 5be27f1e3e ("ALSA: hda/tas2781: Add tas2781 HDA driver")
Reported-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Closes: https://lore.kernel.org/r/9f910785-e856-1539-e3e4-c9817af5fe67@linux.intel.com
Link: https://lore.kernel.org/r/20230820172635.22236-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-08-21 16:20:55 +02:00
Takashi Iwai
1c80cc055b ALSA: hda/tas2781: Fix acpi device refcount leak at tas2781_read_acpi()
The error path at tas2781_read_acpi() doesn't release the acpi_device
adev but releases another device physdev instead.  This results in a
refcount leak.  Fix it by replacing with the right object.

Fixes: 5be27f1e3e ("ALSA: hda/tas2781: Add tas2781 HDA driver")
Reported-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Closes: https://lore.kernel.org/r/9f910785-e856-1539-e3e4-c9817af5fe67@linux.intel.com
Link: https://lore.kernel.org/r/20230820172635.22236-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-08-21 16:20:54 +02:00
Shenghao Ding
5be27f1e3e ALSA: hda/tas2781: Add tas2781 HDA driver
Create tas2781 side codec HDA driver for Lenovo Laptops. The quantity
of the speakers has been define in ACPI. All of the tas2781s in the
laptop will be aggregated as one audio speaker. The code supports
realtek codec as the primary codec. Code offers several controls for
digtial/analog gain setting during playback, and other for eq params
setting in case of different audio profiles, such as music, voice,
movie, etc.

[ adjusted patch to be applied to the latest for-next branch -- tiwai ]

Signed-off-by: Shenghao Ding <shenghao-ding@ti.com>
Link: https://lore.kernel.org/r/20230818085836.1442-2-shenghao-ding@ti.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-08-18 12:14:43 +02:00