mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-05-04 14:23:46 +00:00
ASoC: jack: Add support for GPIO descriptor defined jack pins
Allow jack GPIO pins be defined also using GPIO descriptor-based interface in addition to legacy GPIO numbers. This is done by adding two new fields to struct snd_soc_jack_gpio: idx and gpiod_dev. Legacy GPIO numbers are used only when GPIO consumer device gpiod_dev is NULL and otherwise idx is the descriptor index within the GPIO consumer device. New function snd_soc_jack_add_gpiods() is added for typical cases where all GPIO descriptor jack pins belong to same GPIO consumer device. For other cases the caller must set the gpiod_dev in struct snd_soc_jack_gpio before calling snd_soc_jack_add_gpios(). Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> Signed-off-by: Mark Brown <broonie@linaro.org>
This commit is contained in:
parent
50dfb69d1b
commit
f025d3b9c6
2 changed files with 71 additions and 16 deletions
|
@ -453,6 +453,9 @@ int snd_soc_jack_get_type(struct snd_soc_jack *jack, int micbias_voltage);
|
||||||
#ifdef CONFIG_GPIOLIB
|
#ifdef CONFIG_GPIOLIB
|
||||||
int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
|
int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
|
||||||
struct snd_soc_jack_gpio *gpios);
|
struct snd_soc_jack_gpio *gpios);
|
||||||
|
int snd_soc_jack_add_gpiods(struct device *gpiod_dev,
|
||||||
|
struct snd_soc_jack *jack,
|
||||||
|
int count, struct snd_soc_jack_gpio *gpios);
|
||||||
void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
|
void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
|
||||||
struct snd_soc_jack_gpio *gpios);
|
struct snd_soc_jack_gpio *gpios);
|
||||||
#else
|
#else
|
||||||
|
@ -462,6 +465,13 @@ static inline int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int snd_soc_jack_add_gpiods(struct device *gpiod_dev,
|
||||||
|
struct snd_soc_jack *jack,
|
||||||
|
int count, struct snd_soc_jack_gpio *gpios)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
|
static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
|
||||||
struct snd_soc_jack_gpio *gpios)
|
struct snd_soc_jack_gpio *gpios)
|
||||||
{
|
{
|
||||||
|
@ -586,7 +596,9 @@ struct snd_soc_jack_zone {
|
||||||
/**
|
/**
|
||||||
* struct snd_soc_jack_gpio - Describes a gpio pin for jack detection
|
* struct snd_soc_jack_gpio - Describes a gpio pin for jack detection
|
||||||
*
|
*
|
||||||
* @gpio: gpio number
|
* @gpio: legacy gpio number
|
||||||
|
* @idx: gpio descriptor index within the GPIO consumer device
|
||||||
|
* @gpiod_dev GPIO consumer device
|
||||||
* @name: gpio name
|
* @name: gpio name
|
||||||
* @report: value to report when jack detected
|
* @report: value to report when jack detected
|
||||||
* @invert: report presence in low state
|
* @invert: report presence in low state
|
||||||
|
@ -598,6 +610,8 @@ struct snd_soc_jack_zone {
|
||||||
*/
|
*/
|
||||||
struct snd_soc_jack_gpio {
|
struct snd_soc_jack_gpio {
|
||||||
unsigned int gpio;
|
unsigned int gpio;
|
||||||
|
unsigned int idx;
|
||||||
|
struct device *gpiod_dev;
|
||||||
const char *name;
|
const char *name;
|
||||||
int report;
|
int report;
|
||||||
int invert;
|
int invert;
|
||||||
|
|
|
@ -298,24 +298,41 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
if (!gpio_is_valid(gpios[i].gpio)) {
|
|
||||||
dev_err(jack->codec->dev, "ASoC: Invalid gpio %d\n",
|
|
||||||
gpios[i].gpio);
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto undo;
|
|
||||||
}
|
|
||||||
if (!gpios[i].name) {
|
if (!gpios[i].name) {
|
||||||
dev_err(jack->codec->dev, "ASoC: No name for gpio %d\n",
|
dev_err(jack->codec->dev,
|
||||||
gpios[i].gpio);
|
"ASoC: No name for gpio at index %d\n", i);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto undo;
|
goto undo;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = gpio_request(gpios[i].gpio, gpios[i].name);
|
if (gpios[i].gpiod_dev) {
|
||||||
if (ret)
|
/* GPIO descriptor */
|
||||||
goto undo;
|
gpios[i].desc = gpiod_get_index(gpios[i].gpiod_dev,
|
||||||
|
gpios[i].name,
|
||||||
|
gpios[i].idx);
|
||||||
|
if (IS_ERR(gpios[i].desc)) {
|
||||||
|
ret = PTR_ERR(gpios[i].desc);
|
||||||
|
dev_err(gpios[i].gpiod_dev,
|
||||||
|
"ASoC: Cannot get gpio at index %d: %d",
|
||||||
|
i, ret);
|
||||||
|
goto undo;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* legacy GPIO number */
|
||||||
|
if (!gpio_is_valid(gpios[i].gpio)) {
|
||||||
|
dev_err(jack->codec->dev,
|
||||||
|
"ASoC: Invalid gpio %d\n",
|
||||||
|
gpios[i].gpio);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto undo;
|
||||||
|
}
|
||||||
|
|
||||||
gpios[i].desc = gpio_to_desc(gpios[i].gpio);
|
ret = gpio_request(gpios[i].gpio, gpios[i].name);
|
||||||
|
if (ret)
|
||||||
|
goto undo;
|
||||||
|
|
||||||
|
gpios[i].desc = gpio_to_desc(gpios[i].gpio);
|
||||||
|
}
|
||||||
|
|
||||||
ret = gpiod_direction_input(gpios[i].desc);
|
ret = gpiod_direction_input(gpios[i].desc);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -336,9 +353,9 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
|
||||||
if (gpios[i].wake) {
|
if (gpios[i].wake) {
|
||||||
ret = irq_set_irq_wake(gpiod_to_irq(gpios[i].desc), 1);
|
ret = irq_set_irq_wake(gpiod_to_irq(gpios[i].desc), 1);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
dev_err(jack->codec->dev, "ASoC: "
|
dev_err(jack->codec->dev,
|
||||||
"Failed to mark GPIO %d as wake source: %d\n",
|
"ASoC: Failed to mark GPIO at index %d as wake source: %d\n",
|
||||||
gpios[i].gpio, ret);
|
i, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expose GPIO value over sysfs for diagnostic purposes */
|
/* Expose GPIO value over sysfs for diagnostic purposes */
|
||||||
|
@ -360,6 +377,30 @@ undo:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpios);
|
EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpios);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_soc_jack_add_gpiods - Associate GPIO descriptor pins with an ASoC jack
|
||||||
|
*
|
||||||
|
* @gpiod_dev: GPIO consumer device
|
||||||
|
* @jack: ASoC jack
|
||||||
|
* @count: number of pins
|
||||||
|
* @gpios: array of gpio pins
|
||||||
|
*
|
||||||
|
* This function will request gpio, set data direction and request irq
|
||||||
|
* for each gpio in the array.
|
||||||
|
*/
|
||||||
|
int snd_soc_jack_add_gpiods(struct device *gpiod_dev,
|
||||||
|
struct snd_soc_jack *jack,
|
||||||
|
int count, struct snd_soc_jack_gpio *gpios)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
gpios[i].gpiod_dev = gpiod_dev;
|
||||||
|
|
||||||
|
return snd_soc_jack_add_gpios(jack, count, gpios);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpiods);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_soc_jack_free_gpios - Release GPIO pins' resources of an ASoC jack
|
* snd_soc_jack_free_gpios - Release GPIO pins' resources of an ASoC jack
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Reference in a new issue