hc
2024-08-09 7e81648b513354a6e48db198b3772366e077ffa1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright 2011 Broadcom Corporation.  All rights reserved. */
 
#ifndef __SOUND_ARM_BCM2835_H
#define __SOUND_ARM_BCM2835_H
 
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/raspberrypi/vchiq.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm-indirect.h>
 
#define MAX_SUBSTREAMS   (8)
#define AVAIL_SUBSTREAMS_MASK  (0xff)
 
enum {
   CTRL_VOL_MUTE,
   CTRL_VOL_UNMUTE
};
 
/* macros for alsa2chip and chip2alsa, instead of functions */
 
// convert alsa to chip volume (defined as macro rather than function call)
#define alsa2chip(vol) (uint)(-(((vol) << 8) / 100))
 
// convert chip to alsa volume
#define chip2alsa(vol) -(((vol) * 100) >> 8)
 
#define CHIP_MIN_VOLUME        26214 /* minimum level aka mute */
 
/* Some constants for values .. */
enum snd_bcm2835_route {
   AUDIO_DEST_AUTO = 0,
   AUDIO_DEST_HEADPHONES = 1,
   AUDIO_DEST_HDMI = 2,
   AUDIO_DEST_MAX,
};
 
enum snd_bcm2835_ctrl {
   PCM_PLAYBACK_VOLUME,
   PCM_PLAYBACK_MUTE,
   PCM_PLAYBACK_DEVICE,
};
 
struct bcm2835_vchi_ctx {
   struct vchiq_instance *instance;
};
 
/* definition of the chip-specific record */
struct bcm2835_chip {
   struct snd_card *card;
   struct snd_pcm *pcm;
   struct snd_pcm *pcm_spdif;
   struct device *dev;
   struct bcm2835_alsa_stream *alsa_stream[MAX_SUBSTREAMS];
 
   int volume;
   int dest;
   int mute;
 
   unsigned int opened;
   unsigned int spdif_status;
   struct mutex audio_mutex;
 
   struct bcm2835_vchi_ctx *vchi_ctx;
};
 
struct bcm2835_alsa_stream {
   struct bcm2835_chip *chip;
   struct snd_pcm_substream *substream;
   struct snd_pcm_indirect pcm_indirect;
 
   int draining;
 
   atomic_t pos;
   unsigned int period_offset;
   unsigned int buffer_size;
   unsigned int period_size;
   ktime_t interpolate_start;
 
   struct bcm2835_audio_instance *instance;
   int idx;
};
 
int snd_bcm2835_new_ctl(struct bcm2835_chip *chip);
int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, const char *name,
           int idx, enum snd_bcm2835_route route,
           u32 numchannels, bool spdif);
 
int snd_bcm2835_new_hdmi_ctl(struct bcm2835_chip *chip);
int snd_bcm2835_new_headphones_ctl(struct bcm2835_chip *chip);
 
int bcm2835_new_vchi_ctx(struct device *dev, struct bcm2835_vchi_ctx *vchi_ctx);
void bcm2835_free_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx);
 
int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream);
int bcm2835_audio_close(struct bcm2835_alsa_stream *alsa_stream);
int bcm2835_audio_set_params(struct bcm2835_alsa_stream *alsa_stream,
                unsigned int channels, unsigned int samplerate,
                unsigned int bps);
int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream);
int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream);
int bcm2835_audio_drain(struct bcm2835_alsa_stream *alsa_stream);
int bcm2835_audio_set_ctls(struct bcm2835_alsa_stream *alsa_stream);
int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream,
           unsigned int count,
           void *src);
void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream,
              unsigned int size);
unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream);
 
#endif /* __SOUND_ARM_BCM2835_H */