sound/ppc/pmac.c

Source file repositories/reference/linux-study-clean/sound/ppc/pmac.c

File Facts

System
Linux kernel
Corpus path
sound/ppc/pmac.c
Extension
.c
Size
36520 bytes
Lines
1364
Domain
Driver Families
Bucket
sound/ppc
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, &chip->reg_lock) {
			snd_pmac_beep_stop(chip);
			snd_pmac_pcm_set_format(chip);
			for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++)
				out_le16(&cp->command, command);
			snd_pmac_dma_set_command(rec, &rec->cmd);
			(void)in_le32(&rec->dma->status);
			snd_pmac_dma_run(rec, RUN|WAKE);
			rec->running = 1;
		}
		break;

	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
		scoped_guard(spinlock, &chip->reg_lock) {
			rec->running = 0;
			snd_pmac_dma_stop(rec);
			for (i = 0, cp = rec->cmd.cmds; i < rec->nperiods; i++, cp++)
				out_le16(&cp->command, DBDMA_STOP);
		}
		break;

	default:
		return -EINVAL;
	}

	return 0;
}

/*
 * return the current pointer
 */
inline
static snd_pcm_uframes_t snd_pmac_pcm_pointer(struct snd_pmac *chip,
					      struct pmac_stream *rec,
					      struct snd_pcm_substream *subs)
{
	int count = 0;

#if 1 /* hmm.. how can we get the current dma pointer?? */
	int stat;
	volatile struct dbdma_cmd __iomem *cp = &rec->cmd.cmds[rec->cur_period];
	stat = le16_to_cpu(cp->xfer_status);
	if (stat & (ACTIVE|DEAD)) {
		count = in_le16(&cp->res_count);
		if (count)
			count = rec->period_size - count;
	}
#endif
	count += rec->cur_period * rec->period_size;
	return bytes_to_frames(subs->runtime, count);
}

/*
 * playback
 */

static int snd_pmac_playback_prepare(struct snd_pcm_substream *subs)
{
	struct snd_pmac *chip = snd_pcm_substream_chip(subs);
	return snd_pmac_pcm_prepare(chip, &chip->playback, subs);
}

static int snd_pmac_playback_trigger(struct snd_pcm_substream *subs,
				     int cmd)
{
	struct snd_pmac *chip = snd_pcm_substream_chip(subs);
	return snd_pmac_pcm_trigger(chip, &chip->playback, subs, cmd);
}

static snd_pcm_uframes_t snd_pmac_playback_pointer(struct snd_pcm_substream *subs)
{
	struct snd_pmac *chip = snd_pcm_substream_chip(subs);
	return snd_pmac_pcm_pointer(chip, &chip->playback, subs);
}


/*
 * capture
 */

static int snd_pmac_capture_prepare(struct snd_pcm_substream *subs)
{
	struct snd_pmac *chip = snd_pcm_substream_chip(subs);
	return snd_pmac_pcm_prepare(chip, &chip->capture, subs);
}

static int snd_pmac_capture_trigger(struct snd_pcm_substream *subs,
				    int cmd)
{

Annotation

Implementation Notes