blob: 94db02aef7dc4292fc2d780d22415c90b690b3f0 [file] [log] [blame] [edit]
// SPDX-License-Identifier: GPL-2.0-only
//
// KUnit test for the Cirrus Logic cs35l56-shared module.
//
// Copyright (C) 2026 Cirrus Logic, Inc. and
// Cirrus Logic International Semiconductor Ltd.
#include <kunit/resource.h>
#include <kunit/test.h>
#include <kunit/static_stub.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/device/faux.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/regmap.h>
#include <linux/seq_buf.h>
#include <sound/cs35l56.h>
struct cs35l56_shared_test_priv {
struct kunit *test;
struct faux_device *amp_dev;
struct regmap *registers;
struct cs35l56_base *cs35l56_base;
u8 applied_pad_pull_state[CS35L56_MAX_GPIO];
};
struct cs35l56_shared_test_param {
int spkid_gpios[4];
int spkid_pulls[4];
unsigned long gpio_status;
int spkid;
};
KUNIT_DEFINE_ACTION_WRAPPER(faux_device_destroy_wrapper, faux_device_destroy,
struct faux_device *)
KUNIT_DEFINE_ACTION_WRAPPER(regmap_exit_wrapper, regmap_exit, struct regmap *)
static const struct regmap_config cs35l56_shared_test_mock_registers_regmap = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
.max_register = CS35L56_DSP1_PMEM_5114,
.cache_type = REGCACHE_MAPLE,
};
static const struct regmap_bus cs35l56_shared_test_mock_registers_regmap_bus = {
/* No handlers because it is always in cache-only */
};
static unsigned int cs35l56_shared_test_read_gpio_status(struct cs35l56_shared_test_priv *priv)
{
const struct cs35l56_shared_test_param *param = priv->test->param_value;
unsigned int reg_offs, pad_cfg, val;
unsigned int status = 0;
unsigned int mask = 1;
for (reg_offs = 0; reg_offs < CS35L56_MAX_GPIO * sizeof(u32); reg_offs += sizeof(u32)) {
regmap_read(priv->registers, CS35L56_SYNC_GPIO1_CFG + reg_offs, &pad_cfg);
regmap_read(priv->registers, CS35L56_GPIO1_CTRL1 + reg_offs, &val);
/* Only read a value if set as an input pin and as a GPIO */
val &= (CS35L56_GPIO_DIR_MASK | CS35L56_GPIO_FN_MASK);
if ((pad_cfg & CS35L56_PAD_GPIO_IE) &&
(val == (CS35L56_GPIO_DIR_MASK | CS35L56_GPIO_FN_GPIO)))
status |= (param->gpio_status & mask);
mask <<= 1;
}
return status;
}
static int cs35l56_shared_test_updt_gpio_pres(struct cs35l56_shared_test_priv *priv,
unsigned int reg, unsigned int val)
{
int i, ret;
ret = regmap_write(priv->registers, reg, val);
if (ret)
return ret;
if (val & CS35L56_UPDT_GPIO_PRES) {
/* Simulate transferring register state to internal latches */
for (i = 0; i < ARRAY_SIZE(priv->applied_pad_pull_state); i++) {
reg = CS35L56_SYNC_GPIO1_CFG + (i * sizeof(u32));
regmap_read(priv->registers, reg, &val);
val = FIELD_GET(CS35L56_PAD_GPIO_PULL_MASK, val);
priv->applied_pad_pull_state[i] = val;
}
}
return 0;
}
static int cs35l56_shared_test_reg_read(void *context, unsigned int reg, unsigned int *val)
{
struct cs35l56_shared_test_priv *priv = context;
switch (reg) {
case CS35L56_SYNC_GPIO1_CFG ... CS35L56_ASP2_DIO_GPIO13_CFG:
case CS35L56_GPIO1_CTRL1 ... CS35L56_GPIO13_CTRL1:
return regmap_read(priv->registers, reg, val);
case CS35L56_UPDATE_REGS:
*val = 0;
return 0;
case CS35L56_GPIO_STATUS1:
*val = cs35l56_shared_test_read_gpio_status(priv);
return 0;
default:
kunit_fail_current_test("Bad regmap read address %#x\n", reg);
return -EINVAL;
}
}
static int cs35l56_shared_test_reg_write(void *context, unsigned int reg, unsigned int val)
{
struct cs35l56_shared_test_priv *priv = context;
switch (reg) {
case CS35L56_UPDATE_REGS:
return cs35l56_shared_test_updt_gpio_pres(priv, reg, val);
case CS35L56_SYNC_GPIO1_CFG ... CS35L56_ASP2_DIO_GPIO13_CFG:
case CS35L56_GPIO1_CTRL1 ... CS35L56_GPIO13_CTRL1:
return regmap_write(priv->registers, reg, val);
default:
kunit_fail_current_test("Bad regmap write address %#x\n", reg);
return -EINVAL;
}
}
static const struct regmap_bus cs35l56_shared_test_regmap_bus = {
.reg_read = cs35l56_shared_test_reg_read,
.reg_write = cs35l56_shared_test_reg_write,
.reg_format_endian_default = REGMAP_ENDIAN_LITTLE,
.val_format_endian_default = REGMAP_ENDIAN_LITTLE,
};
/*
* Self-test that the mock GPIO registers obey the configuration bits.
* Other tests rely on the mocked registers only returning a GPIO state
* if the pin is correctly set as a GPIO input.
*/
static void cs35l56_shared_test_mock_gpio_status_selftest(struct kunit *test)
{
const struct cs35l56_shared_test_param *param = test->param_value;
struct cs35l56_shared_test_priv *priv = test->priv;
struct cs35l56_base *cs35l56_base = priv->cs35l56_base;
unsigned int reg, val;
KUNIT_ASSERT_NOT_NULL(test, param);
/* Set all pins non-GPIO and output. Mock GPIO_STATUS should read 0 */
for (reg = CS35L56_GPIO1_CTRL1; reg <= CS35L56_GPIO13_CTRL1; reg += sizeof(u32))
KUNIT_ASSERT_EQ(test, 0, regmap_write(priv->registers, reg, 0));
/* Set all pads as inputs */
for (reg = CS35L56_SYNC_GPIO1_CFG; reg <= CS35L56_ASP2_DIO_GPIO13_CFG; reg += sizeof(u32))
KUNIT_ASSERT_EQ(test, 0, regmap_write(priv->registers, reg, CS35L56_PAD_GPIO_IE));
KUNIT_ASSERT_EQ(test, 0, regmap_read(cs35l56_base->regmap, CS35L56_GPIO_STATUS1, &val));
KUNIT_EXPECT_EQ(test, val, 0);
/* Set all pins as GPIO outputs. Mock GPIO_STATUS should read 0 */
for (reg = CS35L56_GPIO1_CTRL1; reg <= CS35L56_GPIO13_CTRL1; reg += sizeof(u32))
KUNIT_ASSERT_EQ(test, 0, regmap_write(priv->registers, reg, CS35L56_GPIO_FN_GPIO));
KUNIT_ASSERT_EQ(test, 0, regmap_read(cs35l56_base->regmap, CS35L56_GPIO_STATUS1, &val));
KUNIT_EXPECT_EQ(test, val, 0);
/* Set all pins as non-GPIO inputs. Mock GPIO_STATUS should read 0 */
for (reg = CS35L56_GPIO1_CTRL1; reg <= CS35L56_GPIO13_CTRL1; reg += sizeof(u32))
KUNIT_ASSERT_EQ(test, 0, regmap_write(priv->registers, reg, CS35L56_GPIO_DIR_MASK));
KUNIT_ASSERT_EQ(test, 0, regmap_read(cs35l56_base->regmap, CS35L56_GPIO_STATUS1, &val));
KUNIT_EXPECT_EQ(test, val, 0);
/* Set all pins as GPIO inputs. Mock GPIO_STATUS should match param->gpio_status */
for (reg = CS35L56_GPIO1_CTRL1; reg <= CS35L56_GPIO13_CTRL1; reg += sizeof(u32))
KUNIT_ASSERT_EQ(test, 0,
regmap_write(priv->registers, reg,
CS35L56_GPIO_DIR_MASK | CS35L56_GPIO_FN_GPIO));
KUNIT_ASSERT_EQ(test, 0, regmap_read(cs35l56_base->regmap, CS35L56_GPIO_STATUS1, &val));
KUNIT_EXPECT_EQ(test, val, param->gpio_status);
/* Set all pads as outputs. Mock GPIO_STATUS should read 0 */
for (reg = CS35L56_SYNC_GPIO1_CFG; reg <= CS35L56_ASP2_DIO_GPIO13_CFG; reg += sizeof(u32))
KUNIT_ASSERT_EQ(test, 0, regmap_write(priv->registers, reg, 0));
KUNIT_ASSERT_EQ(test, 0, regmap_read(cs35l56_base->regmap, CS35L56_GPIO_STATUS1, &val));
KUNIT_EXPECT_EQ(test, val, 0);
}
/* Test that the listed chip pins are assembled into a speaker ID integer. */
static void cs35l56_shared_test_get_onchip_speaker_id(struct kunit *test)
{
const struct cs35l56_shared_test_param *param = test->param_value;
struct cs35l56_shared_test_priv *priv = test->priv;
struct cs35l56_base *cs35l56_base = priv->cs35l56_base;
unsigned int i, reg;
/* Set all pins non-GPIO and output */
for (reg = CS35L56_GPIO1_CTRL1; reg <= CS35L56_GPIO13_CTRL1; reg += sizeof(u32))
KUNIT_ASSERT_EQ(test, 0, regmap_write(priv->registers, reg, 0));
for (reg = CS35L56_SYNC_GPIO1_CFG; reg <= CS35L56_ASP2_DIO_GPIO13_CFG; reg += sizeof(u32))
KUNIT_ASSERT_EQ(test, 0, regmap_write(priv->registers, reg, 0));
/* Init GPIO array */
for (i = 0; i < ARRAY_SIZE(param->spkid_gpios); i++) {
if (param->spkid_gpios[i] < 0)
break;
cs35l56_base->onchip_spkid_gpios[i] = param->spkid_gpios[i] - 1;
cs35l56_base->num_onchip_spkid_gpios++;
}
cs35l56_base->num_onchip_spkid_pulls = 0;
KUNIT_EXPECT_EQ(test, cs35l56_configure_onchip_spkid_pads(cs35l56_base), 0);
KUNIT_EXPECT_EQ(test, cs35l56_read_onchip_spkid(cs35l56_base), param->spkid);
}
/* Test that the listed chip pins and the corresponding pads are configured correctly. */
static void cs35l56_shared_test_onchip_speaker_id_pad_config(struct kunit *test)
{
const struct cs35l56_shared_test_param *param = test->param_value;
struct cs35l56_shared_test_priv *priv = test->priv;
struct cs35l56_base *cs35l56_base = priv->cs35l56_base;
unsigned int i, reg, val;
/* Init values in all pin registers */
for (reg = CS35L56_GPIO1_CTRL1; reg <= CS35L56_GPIO13_CTRL1; reg += sizeof(u32))
KUNIT_ASSERT_EQ(test, 0, regmap_write(priv->registers, reg, 0));
for (reg = CS35L56_SYNC_GPIO1_CFG; reg <= CS35L56_ASP2_DIO_GPIO13_CFG; reg += sizeof(u32))
KUNIT_ASSERT_EQ(test, 0, regmap_write(priv->registers, reg, 0));
/* Init GPIO array */
for (i = 0; i < ARRAY_SIZE(param->spkid_gpios); i++) {
if (param->spkid_gpios[i] < 0)
break;
cs35l56_base->onchip_spkid_gpios[i] = param->spkid_gpios[i] - 1;
cs35l56_base->num_onchip_spkid_gpios++;
}
/* Init pulls array */
for (i = 0; i < ARRAY_SIZE(param->spkid_pulls); i++) {
if (param->spkid_pulls[i] < 0)
break;
cs35l56_base->onchip_spkid_pulls[i] = param->spkid_pulls[i];
cs35l56_base->num_onchip_spkid_pulls++;
}
KUNIT_EXPECT_EQ(test, cs35l56_configure_onchip_spkid_pads(cs35l56_base), 0);
for (i = 0; i < ARRAY_SIZE(param->spkid_gpios); i++) {
if (param->spkid_gpios[i] < 0)
break;
/* Pad should be an input */
reg = CS35L56_SYNC_GPIO1_CFG + ((param->spkid_gpios[i] - 1) * sizeof(u32));
KUNIT_EXPECT_EQ(test, regmap_read(priv->registers, reg, &val), 0);
KUNIT_EXPECT_EQ(test, val & CS35L56_PAD_GPIO_IE, CS35L56_PAD_GPIO_IE);
/* Specified pulls should be set, others should be none */
if (i < cs35l56_base->num_onchip_spkid_pulls) {
KUNIT_EXPECT_EQ(test, val & CS35L56_PAD_GPIO_PULL_MASK,
FIELD_PREP(CS35L56_PAD_GPIO_PULL_MASK,
param->spkid_pulls[i]));
} else {
KUNIT_EXPECT_EQ(test, val & CS35L56_PAD_GPIO_PULL_MASK,
CS35L56_PAD_PULL_NONE);
}
/* Pulls for all specfied GPIOs should have been transferred to AO latch */
if (i < cs35l56_base->num_onchip_spkid_pulls) {
KUNIT_EXPECT_EQ(test,
priv->applied_pad_pull_state[param->spkid_gpios[i] - 1],
param->spkid_pulls[i]);
} else {
KUNIT_EXPECT_EQ(test,
priv->applied_pad_pull_state[param->spkid_gpios[i] - 1],
CS35L56_PAD_PULL_NONE);
}
}
}
/* Test that the listed chip pins are stashed correctly. */
static void cs35l56_shared_test_stash_onchip_spkid_pins(struct kunit *test)
{
const struct cs35l56_shared_test_param *param = test->param_value;
struct cs35l56_shared_test_priv *priv = test->priv;
struct cs35l56_base *cs35l56_base = priv->cs35l56_base;
u32 gpios[5], pulls[5];
int i, num_gpios, num_pulls;
static_assert(ARRAY_SIZE(gpios) >= ARRAY_SIZE(param->spkid_gpios));
static_assert(ARRAY_SIZE(pulls) >= ARRAY_SIZE(param->spkid_pulls));
num_gpios = 0;
for (i = 0; i < ARRAY_SIZE(param->spkid_gpios); i++) {
if (param->spkid_gpios[i] < 0)
break;
gpios[i] = (u32)param->spkid_gpios[i];
num_gpios++;
}
num_pulls = 0;
for (i = 0; i < ARRAY_SIZE(param->spkid_pulls); i++) {
if (param->spkid_pulls[i] < 0)
break;
pulls[i] = (u32)param->spkid_pulls[i];
num_pulls++;
}
cs35l56_base->num_onchip_spkid_gpios = 0;
cs35l56_base->num_onchip_spkid_pulls = 0;
KUNIT_ASSERT_LE(test, num_gpios, ARRAY_SIZE(cs35l56_base->onchip_spkid_gpios));
KUNIT_ASSERT_LE(test, num_pulls, ARRAY_SIZE(cs35l56_base->onchip_spkid_pulls));
KUNIT_EXPECT_EQ(test,
cs35l56_check_and_save_onchip_spkid_gpios(cs35l56_base,
gpios, num_gpios,
pulls, num_pulls),
0);
KUNIT_EXPECT_EQ(test, cs35l56_base->num_onchip_spkid_gpios, num_gpios);
KUNIT_EXPECT_EQ(test, cs35l56_base->num_onchip_spkid_pulls, num_pulls);
/* GPIO numbers are adjusted from 1-based to 0-based */
for (i = 0; i < num_gpios; i++)
KUNIT_EXPECT_EQ(test, cs35l56_base->onchip_spkid_gpios[i], gpios[i] - 1);
for (i = 0; i < num_pulls; i++)
KUNIT_EXPECT_EQ(test, cs35l56_base->onchip_spkid_pulls[i], pulls[i]);
}
/* Test that illegal GPIO numbers are rejected. */
static void cs35l56_shared_test_stash_onchip_spkid_pins_reject_invalid(struct kunit *test)
{
struct cs35l56_shared_test_priv *priv = test->priv;
struct cs35l56_base *cs35l56_base = priv->cs35l56_base;
u32 gpios[8] = { }, pulls[8] = { };
KUNIT_EXPECT_LE(test,
cs35l56_check_and_save_onchip_spkid_gpios(cs35l56_base,
gpios, 1,
pulls, 0),
0);
switch (cs35l56_base->type) {
case 0x54:
case 0x56:
case 0x57:
gpios[0] = CS35L56_MAX_GPIO + 1;
break;
case 0x63:
gpios[0] = CS35L63_MAX_GPIO + 1;
break;
default:
kunit_fail_current_test("Unsupported type:%#x\n", cs35l56_base->type);
return;
}
KUNIT_EXPECT_LE(test,
cs35l56_check_and_save_onchip_spkid_gpios(cs35l56_base,
gpios, 1,
pulls, 0),
0);
gpios[0] = 1;
pulls[0] = 3;
KUNIT_EXPECT_LE(test,
cs35l56_check_and_save_onchip_spkid_gpios(cs35l56_base,
gpios, 1,
pulls, 1),
0);
static_assert(ARRAY_SIZE(gpios) > ARRAY_SIZE(cs35l56_base->onchip_spkid_gpios));
static_assert(ARRAY_SIZE(pulls) > ARRAY_SIZE(cs35l56_base->onchip_spkid_pulls));
KUNIT_EXPECT_EQ(test,
cs35l56_check_and_save_onchip_spkid_gpios(cs35l56_base,
gpios, ARRAY_SIZE(gpios),
pulls, 0),
-EOVERFLOW);
KUNIT_EXPECT_EQ(test,
cs35l56_check_and_save_onchip_spkid_gpios(cs35l56_base,
gpios, 1,
pulls, ARRAY_SIZE(pulls)),
-EOVERFLOW);
}
static void cs35l56_shared_test_onchip_speaker_id_not_defined(struct kunit *test)
{
struct cs35l56_shared_test_priv *priv = test->priv;
struct cs35l56_base *cs35l56_base = priv->cs35l56_base;
memset(cs35l56_base->onchip_spkid_gpios, 0, sizeof(cs35l56_base->onchip_spkid_gpios));
memset(cs35l56_base->onchip_spkid_pulls, 0, sizeof(cs35l56_base->onchip_spkid_pulls));
cs35l56_base->num_onchip_spkid_gpios = 0;
cs35l56_base->num_onchip_spkid_pulls = 0;
KUNIT_EXPECT_EQ(test, cs35l56_configure_onchip_spkid_pads(cs35l56_base), 0);
KUNIT_EXPECT_EQ(test, cs35l56_read_onchip_spkid(cs35l56_base), -ENOENT);
}
static int cs35l56_shared_test_case_regmap_init(struct kunit *test,
const struct regmap_config *regmap_config)
{
struct cs35l56_shared_test_priv *priv = test->priv;
struct cs35l56_base *cs35l56_base;
/*
* Create a dummy regmap to simulate a register map by holding the
* values of all simulated registers in the regmap cache.
*/
priv->registers = regmap_init(&priv->amp_dev->dev,
&cs35l56_shared_test_mock_registers_regmap_bus,
priv,
&cs35l56_shared_test_mock_registers_regmap);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->registers);
KUNIT_ASSERT_EQ(test, 0,
kunit_add_action_or_reset(test, regmap_exit_wrapper,
priv->registers));
regcache_cache_only(priv->registers, true);
/* Create dummy regmap for cs35l56 driver */
cs35l56_base = priv->cs35l56_base;
cs35l56_base->regmap = regmap_init(cs35l56_base->dev,
&cs35l56_shared_test_regmap_bus,
priv,
regmap_config);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cs35l56_base->regmap);
KUNIT_ASSERT_EQ(test, 0,
kunit_add_action_or_reset(test, regmap_exit_wrapper,
cs35l56_base->regmap));
return 0;
}
static int cs35l56_shared_test_case_base_init(struct kunit *test, u8 type, u8 rev,
const struct regmap_config *regmap_config)
{
struct cs35l56_shared_test_priv *priv;
int ret;
KUNIT_ASSERT_NOT_NULL(test, cs_amp_test_hooks);
priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
test->priv = priv;
priv->test = test;
/* Create dummy amp driver dev */
priv->amp_dev = faux_device_create("cs35l56_shared_test_drv", NULL, NULL);
KUNIT_ASSERT_NOT_NULL(test, priv->amp_dev);
KUNIT_ASSERT_EQ(test, 0,
kunit_add_action_or_reset(test,
faux_device_destroy_wrapper,
priv->amp_dev));
priv->cs35l56_base = kunit_kzalloc(test, sizeof(*priv->cs35l56_base), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, priv->cs35l56_base);
priv->cs35l56_base->dev = &priv->amp_dev->dev;
priv->cs35l56_base->type = type;
priv->cs35l56_base->rev = rev;
if (regmap_config) {
ret = cs35l56_shared_test_case_regmap_init(test, regmap_config);
if (ret)
return ret;
}
return 0;
}
static int cs35l56_shared_test_case_regmap_init_L56_B0_sdw(struct kunit *test)
{
return cs35l56_shared_test_case_base_init(test, 0x56, 0xb0, &cs35l56_regmap_sdw);
}
static int cs35l56_shared_test_case_regmap_init_L56_B0_spi(struct kunit *test)
{
return cs35l56_shared_test_case_base_init(test, 0x56, 0xb0, &cs35l56_regmap_spi);
}
static int cs35l56_shared_test_case_regmap_init_L56_B0_i2c(struct kunit *test)
{
return cs35l56_shared_test_case_base_init(test, 0x56, 0xb0, &cs35l56_regmap_i2c);
}
static int cs35l56_shared_test_case_regmap_init_L56_B2_sdw(struct kunit *test)
{
return cs35l56_shared_test_case_base_init(test, 0x56, 0xb2, &cs35l56_regmap_sdw);
}
static int cs35l56_shared_test_case_regmap_init_L56_B2_spi(struct kunit *test)
{
return cs35l56_shared_test_case_base_init(test, 0x56, 0xb2, &cs35l56_regmap_spi);
}
static int cs35l56_shared_test_case_regmap_init_L56_B2_i2c(struct kunit *test)
{
return cs35l56_shared_test_case_base_init(test, 0x56, 0xb2, &cs35l56_regmap_i2c);
}
static int cs35l56_shared_test_case_regmap_init_L63_A1_sdw(struct kunit *test)
{
return cs35l56_shared_test_case_base_init(test, 0x63, 0xa1, &cs35l63_regmap_sdw);
}
static void cs35l56_shared_test_gpio_param_desc(const struct cs35l56_shared_test_param *param,
char *desc)
{
DECLARE_SEQ_BUF(gpios, 1 + (2 * ARRAY_SIZE(param->spkid_gpios)));
DECLARE_SEQ_BUF(pulls, 1 + (2 * ARRAY_SIZE(param->spkid_pulls)));
int i;
for (i = 0; i < ARRAY_SIZE(param->spkid_gpios); i++) {
if (param->spkid_gpios[i] < 0)
break;
seq_buf_printf(&gpios, "%s%d", (i == 0) ? "" : ",", param->spkid_gpios[i]);
}
for (i = 0; i < ARRAY_SIZE(param->spkid_pulls); i++) {
if (param->spkid_pulls[i] < 0)
break;
seq_buf_printf(&pulls, "%s%d", (i == 0) ? "" : ",", param->spkid_pulls[i]);
}
snprintf(desc, KUNIT_PARAM_DESC_SIZE, "gpios:{%s} pulls:{%s} status:%#lx spkid:%d",
seq_buf_str(&gpios), seq_buf_str(&pulls), param->gpio_status, param->spkid);
}
static const struct cs35l56_shared_test_param cs35l56_shared_test_gpios_selftest_cases[] = {
{ .spkid_gpios = { -1 }, .gpio_status = GENMASK(12, 0) },
};
KUNIT_ARRAY_PARAM(cs35l56_shared_test_gpios_selftest,
cs35l56_shared_test_gpios_selftest_cases,
cs35l56_shared_test_gpio_param_desc);
static const struct cs35l56_shared_test_param cs35l56_shared_test_onchip_spkid_cases[] = {
{ .spkid_gpios = { 1, -1 }, .gpio_status = 0, .spkid = 0 },
{ .spkid_gpios = { 1, -1 }, .gpio_status = ~BIT(0), .spkid = 0 },
{ .spkid_gpios = { 1, -1 }, .gpio_status = BIT(0), .spkid = 1 },
{ .spkid_gpios = { 7, -1 }, .gpio_status = 0, .spkid = 0 },
{ .spkid_gpios = { 7, -1 }, .gpio_status = ~BIT(6), .spkid = 0 },
{ .spkid_gpios = { 7, -1 }, .gpio_status = BIT(6), .spkid = 1 },
{ .spkid_gpios = { 1, 7, -1 }, .gpio_status = 0, .spkid = 0 },
{ .spkid_gpios = { 1, 7, -1 }, .gpio_status = ~(BIT(0) | BIT(6)), .spkid = 0 },
{ .spkid_gpios = { 1, 7, -1 }, .gpio_status = BIT(6), .spkid = 1 },
{ .spkid_gpios = { 1, 7, -1 }, .gpio_status = BIT(0), .spkid = 2 },
{ .spkid_gpios = { 1, 7, -1 }, .gpio_status = BIT(6) | BIT(0), .spkid = 3 },
{ .spkid_gpios = { 7, 1, -1 }, .gpio_status = 0, .spkid = 0 },
{ .spkid_gpios = { 7, 1, -1 }, .gpio_status = ~(BIT(6) | BIT(0)), .spkid = 0 },
{ .spkid_gpios = { 7, 1, -1 }, .gpio_status = BIT(0), .spkid = 1 },
{ .spkid_gpios = { 7, 1, -1 }, .gpio_status = BIT(6), .spkid = 2 },
{ .spkid_gpios = { 7, 1, -1 }, .gpio_status = BIT(6) | BIT(0), .spkid = 3 },
{ .spkid_gpios = { 3, 7, 1, -1 }, .gpio_status = 0, .spkid = 0 },
{ .spkid_gpios = { 3, 7, 1, -1 }, .gpio_status = BIT(0), .spkid = 1 },
{ .spkid_gpios = { 3, 7, 1, -1 }, .gpio_status = BIT(6), .spkid = 2 },
{ .spkid_gpios = { 3, 7, 1, -1 }, .gpio_status = BIT(6) | BIT(0), .spkid = 3 },
{ .spkid_gpios = { 3, 7, 1, -1 }, .gpio_status = BIT(2), .spkid = 4 },
{ .spkid_gpios = { 3, 7, 1, -1 }, .gpio_status = BIT(2) | BIT(0), .spkid = 5 },
{ .spkid_gpios = { 3, 7, 1, -1 }, .gpio_status = BIT(2) | BIT(6), .spkid = 6 },
{ .spkid_gpios = { 3, 7, 1, -1 }, .gpio_status = BIT(2) | BIT(6) | BIT(0), .spkid = 7 },
};
KUNIT_ARRAY_PARAM(cs35l56_shared_test_onchip_spkid, cs35l56_shared_test_onchip_spkid_cases,
cs35l56_shared_test_gpio_param_desc);
static const struct cs35l56_shared_test_param cs35l56_shared_test_onchip_spkid_pull_cases[] = {
{ .spkid_gpios = { 1, -1 }, .spkid_pulls = { 1, -1 }, },
{ .spkid_gpios = { 1, -1 }, .spkid_pulls = { 2, -1 }, },
{ .spkid_gpios = { 7, -1 }, .spkid_pulls = { 1, -1 }, },
{ .spkid_gpios = { 7, -1 }, .spkid_pulls = { 2, -1 }, },
{ .spkid_gpios = { 1, 7, -1 }, .spkid_pulls = { 1, 1, -1 }, },
{ .spkid_gpios = { 1, 7, -1 }, .spkid_pulls = { 2, 2, -1 }, },
{ .spkid_gpios = { 7, 1, -1 }, .spkid_pulls = { 1, 1, -1 }, },
{ .spkid_gpios = { 7, 1, -1 }, .spkid_pulls = { 2, 2, -1 }, },
{ .spkid_gpios = { 3, 7, 1, -1 }, .spkid_pulls = { 1, 1, 1, -1 }, },
{ .spkid_gpios = { 3, 7, 1, -1 }, .spkid_pulls = { 2, 2, 2, -1 }, },
};
KUNIT_ARRAY_PARAM(cs35l56_shared_test_onchip_spkid_pull,
cs35l56_shared_test_onchip_spkid_pull_cases,
cs35l56_shared_test_gpio_param_desc);
static struct kunit_case cs35l56_shared_test_cases[] = {
/* Tests for speaker id */
KUNIT_CASE_PARAM(cs35l56_shared_test_mock_gpio_status_selftest,
cs35l56_shared_test_gpios_selftest_gen_params),
KUNIT_CASE_PARAM(cs35l56_shared_test_get_onchip_speaker_id,
cs35l56_shared_test_onchip_spkid_gen_params),
KUNIT_CASE_PARAM(cs35l56_shared_test_onchip_speaker_id_pad_config,
cs35l56_shared_test_onchip_spkid_gen_params),
KUNIT_CASE_PARAM(cs35l56_shared_test_onchip_speaker_id_pad_config,
cs35l56_shared_test_onchip_spkid_pull_gen_params),
KUNIT_CASE_PARAM(cs35l56_shared_test_stash_onchip_spkid_pins,
cs35l56_shared_test_onchip_spkid_pull_gen_params),
KUNIT_CASE(cs35l56_shared_test_stash_onchip_spkid_pins_reject_invalid),
KUNIT_CASE(cs35l56_shared_test_onchip_speaker_id_not_defined),
{ }
};
static struct kunit_suite cs35l56_shared_test_suite_L56_B0_sdw = {
.name = "snd-soc-cs35l56-shared-test_L56_B0_sdw",
.init = cs35l56_shared_test_case_regmap_init_L56_B0_sdw,
.test_cases = cs35l56_shared_test_cases,
};
static struct kunit_suite cs35l56_shared_test_suite_L56_B2_sdw = {
.name = "snd-soc-cs35l56-shared-test_L56_B2_sdw",
.init = cs35l56_shared_test_case_regmap_init_L56_B2_sdw,
.test_cases = cs35l56_shared_test_cases,
};
static struct kunit_suite cs35l56_shared_test_suite_L63_A1_sdw = {
.name = "snd-soc-cs35l56-shared-test_L63_A1_sdw",
.init = cs35l56_shared_test_case_regmap_init_L63_A1_sdw,
.test_cases = cs35l56_shared_test_cases,
};
static struct kunit_suite cs35l56_shared_test_suite_L56_B0_spi = {
.name = "snd-soc-cs35l56-shared-test_L56_B0_spi",
.init = cs35l56_shared_test_case_regmap_init_L56_B0_spi,
.test_cases = cs35l56_shared_test_cases,
};
static struct kunit_suite cs35l56_shared_test_suite_L56_B2_spi = {
.name = "snd-soc-cs35l56-shared-test_L56_B2_spi",
.init = cs35l56_shared_test_case_regmap_init_L56_B2_spi,
.test_cases = cs35l56_shared_test_cases,
};
static struct kunit_suite cs35l56_shared_test_suite_L56_B0_i2c = {
.name = "snd-soc-cs35l56-shared-test_L56_B0_i2c",
.init = cs35l56_shared_test_case_regmap_init_L56_B0_i2c,
.test_cases = cs35l56_shared_test_cases,
};
static struct kunit_suite cs35l56_shared_test_suite_L56_B2_i2c = {
.name = "snd-soc-cs35l56-shared-test_L56_B2_i2c",
.init = cs35l56_shared_test_case_regmap_init_L56_B2_i2c,
.test_cases = cs35l56_shared_test_cases,
};
kunit_test_suites(
&cs35l56_shared_test_suite_L56_B0_sdw,
&cs35l56_shared_test_suite_L56_B2_sdw,
&cs35l56_shared_test_suite_L63_A1_sdw,
&cs35l56_shared_test_suite_L56_B0_spi,
&cs35l56_shared_test_suite_L56_B2_spi,
&cs35l56_shared_test_suite_L56_B0_i2c,
&cs35l56_shared_test_suite_L56_B2_i2c,
);
MODULE_IMPORT_NS("SND_SOC_CS35L56_SHARED");
MODULE_IMPORT_NS("SND_SOC_CS_AMP_LIB");
MODULE_DESCRIPTION("KUnit test for cs35l56-shared module");
MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
MODULE_LICENSE("GPL");