Skip to content

Commit f3c6051

Browse files
simontrimmerbroonie
authored andcommitted
spi: cs42l43: Add GPIO speaker id support to the bridge configuration
OEMs can use the spk-id-gpios ACPI property to indicate the type of speakers fitted to a device. Attempt to read a spk-id value using the GPIO method when a usable spk-id value is not obtained from the 01fa-spk-id-val ACPI property. Obtaining the spk-id value has been moved earlier in the function to the other sidecar block, so that an -EPROBE_DEFER from a GPIO driver is handled more efficiently. Signed-off-by: Simon Trimmer <simont@opensource.cirrus.com> Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://patch.msgid.link/20241112131434.678882-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent b1e7828 commit f3c6051

File tree

1 file changed

+41
-5
lines changed

1 file changed

+41
-5
lines changed

drivers/spi/spi-cs42l43.c

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/cleanup.h>
1313
#include <linux/device.h>
1414
#include <linux/errno.h>
15+
#include <linux/gpio/consumer.h>
1516
#include <linux/gpio/machine.h>
1617
#include <linux/gpio/property.h>
1718
#include <linux/mfd/cs42l43.h>
@@ -229,6 +230,33 @@ static size_t cs42l43_spi_max_length(struct spi_device *spi)
229230
return CS42L43_SPI_MAX_LENGTH;
230231
}
231232

233+
static int cs42l43_get_speaker_id_gpios(struct cs42l43_spi *priv, int *result)
234+
{
235+
struct gpio_descs *descs;
236+
u32 spkid;
237+
int i, ret;
238+
239+
descs = gpiod_get_array_optional(priv->dev, "spk-id", GPIOD_IN);
240+
if (IS_ERR_OR_NULL(descs))
241+
return PTR_ERR(descs);
242+
243+
spkid = 0;
244+
for (i = 0; i < descs->ndescs; i++) {
245+
ret = gpiod_get_value_cansleep(descs->desc[i]);
246+
if (ret < 0)
247+
goto err;
248+
249+
spkid |= (ret << i);
250+
}
251+
252+
dev_dbg(priv->dev, "spk-id-gpios = %d\n", spkid);
253+
*result = spkid;
254+
err:
255+
gpiod_put_array(descs);
256+
257+
return ret;
258+
}
259+
232260
static struct fwnode_handle *cs42l43_find_xu_node(struct fwnode_handle *fwnode)
233261
{
234262
static const u32 func_smart_amp = 0x1;
@@ -306,6 +334,7 @@ static int cs42l43_spi_probe(struct platform_device *pdev)
306334
struct fwnode_handle *fwnode = dev_fwnode(cs42l43->dev);
307335
struct fwnode_handle *xu_fwnode __free(fwnode_handle) = cs42l43_find_xu_node(fwnode);
308336
int nsidecars = 0;
337+
int spkid = -EINVAL;
309338
int ret;
310339

311340
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
@@ -360,6 +389,18 @@ static int cs42l43_spi_probe(struct platform_device *pdev)
360389
fwnode_property_read_u32(xu_fwnode, "01fa-sidecar-instances", &nsidecars);
361390

362391
if (nsidecars) {
392+
ret = fwnode_property_read_u32(xu_fwnode, "01fa-spk-id-val", &spkid);
393+
if (!ret) {
394+
dev_dbg(priv->dev, "01fa-spk-id-val = %d\n", spkid);
395+
} else if (ret != -EINVAL) {
396+
return dev_err_probe(priv->dev, ret, "Failed to get spk-id-val\n");
397+
} else {
398+
ret = cs42l43_get_speaker_id_gpios(priv, &spkid);
399+
if (ret < 0)
400+
return dev_err_probe(priv->dev, ret,
401+
"Failed to get spk-id-gpios\n");
402+
}
403+
363404
ret = software_node_register(&cs42l43_gpiochip_swnode);
364405
if (ret)
365406
return dev_err_probe(priv->dev, ret,
@@ -385,11 +426,6 @@ static int cs42l43_spi_probe(struct platform_device *pdev)
385426
if (nsidecars) {
386427
struct spi_board_info *ampl_info;
387428
struct spi_board_info *ampr_info;
388-
int spkid = -EINVAL;
389-
390-
fwnode_property_read_u32(xu_fwnode, "01fa-spk-id-val", &spkid);
391-
392-
dev_dbg(priv->dev, "Found speaker ID %d\n", spkid);
393429

394430
ampl_info = cs42l43_create_bridge_amp(priv, "cs35l56-left", 0, spkid);
395431
if (!ampl_info)

0 commit comments

Comments
 (0)