|
|
|
@ -22,30 +22,42 @@ |
|
|
|
|
#include <trace/events/asoc.h> |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* snd_soc_jack_new - Create a new jack |
|
|
|
|
* @codec: ASoC codec |
|
|
|
|
* snd_soc_card_jack_new - Create a new jack |
|
|
|
|
* @card: ASoC card |
|
|
|
|
* @id: an identifying string for this jack |
|
|
|
|
* @type: a bitmask of enum snd_jack_type values that can be detected by |
|
|
|
|
* this jack |
|
|
|
|
* @jack: structure to use for the jack |
|
|
|
|
* @pins: Array of jack pins to be added to the jack or NULL |
|
|
|
|
* @num_pins: Number of elements in the @pins array |
|
|
|
|
* |
|
|
|
|
* Creates a new jack object. |
|
|
|
|
* |
|
|
|
|
* Returns zero if successful, or a negative error code on failure. |
|
|
|
|
* On success jack will be initialised. |
|
|
|
|
*/ |
|
|
|
|
int snd_soc_jack_new(struct snd_soc_codec *codec, const char *id, int type, |
|
|
|
|
struct snd_soc_jack *jack) |
|
|
|
|
int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type, |
|
|
|
|
struct snd_soc_jack *jack, struct snd_soc_jack_pin *pins, |
|
|
|
|
unsigned int num_pins) |
|
|
|
|
{ |
|
|
|
|
int ret; |
|
|
|
|
|
|
|
|
|
mutex_init(&jack->mutex); |
|
|
|
|
jack->codec = codec; |
|
|
|
|
jack->card = card; |
|
|
|
|
INIT_LIST_HEAD(&jack->pins); |
|
|
|
|
INIT_LIST_HEAD(&jack->jack_zones); |
|
|
|
|
BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier); |
|
|
|
|
|
|
|
|
|
return snd_jack_new(codec->component.card->snd_card, id, type, &jack->jack); |
|
|
|
|
ret = snd_jack_new(card->snd_card, id, type, &jack->jack); |
|
|
|
|
if (ret) |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
if (num_pins) |
|
|
|
|
return snd_soc_jack_add_pins(jack, num_pins, pins); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_jack_new); |
|
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_card_jack_new); |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* snd_soc_jack_report - Report the current status for a jack |
|
|
|
@ -63,7 +75,6 @@ EXPORT_SYMBOL_GPL(snd_soc_jack_new); |
|
|
|
|
*/ |
|
|
|
|
void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) |
|
|
|
|
{ |
|
|
|
|
struct snd_soc_codec *codec; |
|
|
|
|
struct snd_soc_dapm_context *dapm; |
|
|
|
|
struct snd_soc_jack_pin *pin; |
|
|
|
|
unsigned int sync = 0; |
|
|
|
@ -74,8 +85,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) |
|
|
|
|
if (!jack) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
codec = jack->codec; |
|
|
|
|
dapm = &codec->dapm; |
|
|
|
|
dapm = &jack->card->dapm; |
|
|
|
|
|
|
|
|
|
mutex_lock(&jack->mutex); |
|
|
|
|
|
|
|
|
@ -175,12 +185,12 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, |
|
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++) { |
|
|
|
|
if (!pins[i].pin) { |
|
|
|
|
dev_err(jack->codec->dev, "ASoC: No name for pin %d\n", |
|
|
|
|
dev_err(jack->card->dev, "ASoC: No name for pin %d\n", |
|
|
|
|
i); |
|
|
|
|
return -EINVAL; |
|
|
|
|
} |
|
|
|
|
if (!pins[i].mask) { |
|
|
|
|
dev_err(jack->codec->dev, "ASoC: No mask for pin %d" |
|
|
|
|
dev_err(jack->card->dev, "ASoC: No mask for pin %d" |
|
|
|
|
" (%s)\n", i, pins[i].pin); |
|
|
|
|
return -EINVAL; |
|
|
|
|
} |
|
|
|
@ -260,7 +270,7 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio) |
|
|
|
|
static irqreturn_t gpio_handler(int irq, void *data) |
|
|
|
|
{ |
|
|
|
|
struct snd_soc_jack_gpio *gpio = data; |
|
|
|
|
struct device *dev = gpio->jack->codec->component.card->dev; |
|
|
|
|
struct device *dev = gpio->jack->card->dev; |
|
|
|
|
|
|
|
|
|
trace_snd_soc_jack_irq(gpio->name); |
|
|
|
|
|
|
|
|
@ -299,7 +309,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, |
|
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++) { |
|
|
|
|
if (!gpios[i].name) { |
|
|
|
|
dev_err(jack->codec->dev, |
|
|
|
|
dev_err(jack->card->dev, |
|
|
|
|
"ASoC: No name for gpio at index %d\n", i); |
|
|
|
|
ret = -EINVAL; |
|
|
|
|
goto undo; |
|
|
|
@ -320,7 +330,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, |
|
|
|
|
} else { |
|
|
|
|
/* legacy GPIO number */ |
|
|
|
|
if (!gpio_is_valid(gpios[i].gpio)) { |
|
|
|
|
dev_err(jack->codec->dev, |
|
|
|
|
dev_err(jack->card->dev, |
|
|
|
|
"ASoC: Invalid gpio %d\n", |
|
|
|
|
gpios[i].gpio); |
|
|
|
|
ret = -EINVAL; |
|
|
|
@ -350,7 +360,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, |
|
|
|
|
if (gpios[i].wake) { |
|
|
|
|
ret = irq_set_irq_wake(gpiod_to_irq(gpios[i].desc), 1); |
|
|
|
|
if (ret != 0) |
|
|
|
|
dev_err(jack->codec->dev, |
|
|
|
|
dev_err(jack->card->dev, |
|
|
|
|
"ASoC: Failed to mark GPIO at index %d as wake source: %d\n", |
|
|
|
|
i, ret); |
|
|
|
|
} |
|
|
|
|