sound/soc/ti/ams-delta.c

Source file repositories/reference/linux-study-clean/sound/soc/ti/ams-delta.c

File Facts

System
Linux kernel
Corpus path
sound/soc/ti/ams-delta.c
Extension
.c
Size
16494 bytes
Lines
610
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

scoped_guard(spinlock_bh, &ams_delta_lock) {
			mod_timer(&cx81801_timer, jiffies + msecs_to_jiffies(150));
			apply = !ams_delta_muted && !cx81801_cmd_pending;
			cx81801_cmd_pending = 1;
		}

		/* Apply config pulse by connecting the codec to the modem
		 * if not already done */
		if (apply)
			gpiod_set_value(gpiod_modem_codec, 1);
		break;
	}
}

/* Line discipline .write_wakeup() */
static void cx81801_wakeup(struct tty_struct *tty)
{
	v253_ops.write_wakeup(tty);
}

static struct tty_ldisc_ops cx81801_ops = {
	.name = "cx81801",
	.num = N_V253,
	.owner = THIS_MODULE,
	.open = cx81801_open,
	.close = cx81801_close,
	.hangup = cx81801_hangup,
	.receive_buf = cx81801_receive,
	.write_wakeup = cx81801_wakeup,
};


/*
 * Even if not very useful, the sound card can still work without any of the
 * above functionality activated.  You can still control its audio input/output
 * constellation and speakerphone gain from userspace by issuing AT commands
 * over the modem port.
 */

static struct snd_soc_ops ams_delta_ops;


/* Digital mute implemented using modem/CPU multiplexer.
 * Shares hardware with codec config pulse generation */
static bool ams_delta_muted = 1;

static int ams_delta_mute(struct snd_soc_dai *dai, int mute, int direction)
{
	int apply;

	if (ams_delta_muted == mute)
		return 0;

	scoped_guard(spinlock_bh, &ams_delta_lock) {
		ams_delta_muted = mute;
		apply = !cx81801_cmd_pending;
	}

	if (apply)
		gpiod_set_value(gpiod_modem_codec, !!mute);
	return 0;
}

/* Our codec DAI probably doesn't have its own .ops structure */
static const struct snd_soc_dai_ops ams_delta_dai_ops = {
	.mute_stream = ams_delta_mute,
	.no_capture_mute = 1,
};

/* Will be used if the codec ever has its own digital_mute function */
static int ams_delta_startup(struct snd_pcm_substream *substream)
{
	return ams_delta_mute(NULL, 0, substream->stream);
}

static void ams_delta_shutdown(struct snd_pcm_substream *substream)
{
	ams_delta_mute(NULL, 1, substream->stream);
}


/*
 * Card initialization
 */

static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
	struct snd_soc_card *card = rtd->card;
	struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);

Annotation

Implementation Notes