Skip to content

Conversation

niranjanhyti
Copy link

No description provided.

@sofci
Copy link
Collaborator

sofci commented Aug 13, 2025

Can one of the admins verify this patch?

reply test this please to run this test once

struct sdw_stream_runtime *sdw_stream;
};

static const struct reg_default tas2783_reg_defaults[] = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is more like reg_sequence instead of reg_default because you write the registers in tas2783_initialize_device.

.reg_bits = 32,
.val_bits = 8,
.readable_reg = tas2783_readable_register,
.volatile_reg = tas2783_volatile_register,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that .reg_defaults is needed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Earlier I used .reg_default alone without manual initialization function tas2783_initialize_device. But the device did not function as expected. So I added manual initialization to duplicate the .reg_defaults behavior and dropped .reg_defaults . Is the .reg_default suppose to do the initialization to the device as well or it this behavior is because of my programming error ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .reg_default should be the default register value of the chip. It is the initial value of the regmap cache and in theory, the .reg_default should include all the readable registers except the volatile registers. And, no, .reg_defaults will not do the initialization to the device, you have to do it by yourself.

for (i = 0; i < ARRAY_SIZE(tas2783_reg_defaults); i++) {
ret = sdw_write_no_pm(tas_dev->sdw_peripheral,
tas2783_reg_defaults[i].reg,
tas2783_reg_defaults[i].def);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use regmap_multi_reg_write


val = tas_clamp(ucontrol->value.integer.value[0],
mc->max, mc->invert);
ret = sdw_write_no_pm(tas_dev->sdw_peripheral, mc->reg, val);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend to use regmap_write if possible. Note that access the register directly will not update the regmap cache.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the information. I believe this applies for the entire driver code. Any general guideline on when it is safe to use the sdw_write/read* functions ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the only scenario to use sdw_write/read is if the register needs to be accessed before the regmap is registered. Or you want to access the register silently. I.e. Without touch the regmap cache.

tas_dev->hw_init = true;
}

tas2783_initialize_device(tas_dev);
Copy link
Collaborator

@bardliao bardliao Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need initialize the device if firmware request failed?

.direction = {true, true},
.dai_name = "tas2783-codec",
.dai_type = SOC_SDW_DAI_TYPE_AMP,
.dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to add the machine driver controls and a .rtd_init to give user a way to switch on/off the speakers? Like

                                .rtd_init = asoc_sdw_rt_amp_spk_rtd_init,
                                .controls = generic_spk_controls,
                                .num_controls = ARRAY_SIZE(generic_spk_controls),
                                .widgets = generic_spk_widgets,
                                .num_widgets = ARRAY_SIZE(generic_spk_widgets),

.links = tas2783_link0,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-mtl-tas2783.tplg",
},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new item should be added after the mockup devices.

@bardliao
Copy link
Collaborator

test this please

@niranjanhyti niranjanhyti force-pushed the for-tas2783a branch 2 times, most recently from 2d2255b to 8b9a614 Compare August 20, 2025 02:55
case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_MFPU26, 0x08, 0):
case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_SAPU29, 0x05, 0):
case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU21, 0x06, 0):
case SDW_SDCA_CTL(1, TAS2783_SDCA_ENT_PPU26, 0x06, 0):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory, all readable registers except the volatile registers need a default value. So I would expect that the registers above will list in tas2783_reg_default[].

u8 *data, u32 size)
{
u32 ts, spk_count, size_calculated;
u32 crc_calculated, crc_read, i;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: redundant space between u32 and crc_calculated.

u32 bit;
unsigned long addr;
struct sdw_dpn_prop *dpn;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will need to call sdw_slave_read_prop(slave); if you need to read some properties from the ACPI table.

.controls = maxim_controls,
.num_controls = ARRAY_SIZE(maxim_controls),
.widgets = maxim_widgets,
.num_widgets = ARRAY_SIZE(maxim_widgets),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move the commits before ASoc: tas2783A: add machine driver changes. So that we can add the above in the ASoc: tas2783A: add machine driver changes commit.

if (!strncmp(prefix, "tas2783-1", strlen("tas2783-1"))) {
strncpy(speaker, "Left Spk", strlen("Left Spk") + 1);
} else if (!strncmp(prefix, "tas2783-2", strlen("tas2783-2"))) {
strncpy(speaker, "Right Spk", strlen("Right Spk") + 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I prefer using a single route like what asoc_sdw_rt_amp_spk_rtd_init does and generic_spk_widgets[]. You may have more than 2 amps in the future.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found that we will have one switch for each amp with this implementation. So I thought it will be helpful for turning off individual channels.
With the suggested method similar to asoc_sdw_rt_amp_spk_rtd_init, there will be only one 'Speaker Switch' mixer control.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, if you need to control left and right separately, you need to create 2 controls.

.dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
.init = asoc_sdw_ti_amp_init,
.rtd_init = asoc_sdw_ti_spk_rtd_init,
.controls = maxim_controls,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a more generic name is needed if you want to reuse the maxim controls/widgets. TI amp uses Maxim controls/widgets is confusing.

TAS2783 is mono digital input class-D Smart Amplifier
based on MIPI Alliance Soundwire interface. The driver
supports loading the algorithm coefficients for one
or more tas2783 chips.

Signed-off-by: Niranjan H Y <[email protected]>

---
v3:
- update default register list
- re-order entiry id in header files and update duplicate
  entry
- indentation issue fixes

v2:
- add default registers
- refactor device initilisation with reg_sequence
- use regmap_read/write APIs for device register
  access for some register access
- initialize the device only on successful firmware
  download
- clear latch before power up and log error
- error handling and retry during power up
- rename the volume mixer control for readability
- modify the widgets for machine driver support

checkpatch issue fix
Signed-off-by: Niranjan H Y <[email protected]>
---
v3:
- re-ordered the commit to appear before machine driver changes
Add tas2783-codec for codec_info

Signed-off-by: Niranjan H Y <[email protected]>
--
v3:
 - generic names for widgets and controls for 2
   channels support.
acpi match changes to support tas2783a on mtl
on link 0

Signed-off-by: Niranjan H Y <[email protected]>

---
v3:
- no changes

v2:
- move ACPI entries for tas2783 after mockup
@bardliao
Copy link
Collaborator

Thanks @niranjanhyti It looks good to me. Please send the patches to the mailing list. Feel free to add my Reviewed-by: Bard Liao <[email protected]> tag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants