2017-01-25 06:57:52 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2016 Intel Corporation
|
|
|
|
* Authors: Sailaja Bandarupalli <sailaja.bandarupalli@intel.com>
|
|
|
|
* Ramesh Babu K V <ramesh.babu@intel.com>
|
|
|
|
* Vaibhav Agarwal <vaibhav.agarwal@intel.com>
|
|
|
|
* Jerome Anand <jerome.anand@intel.com>
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
|
|
* a copy of this software and associated documentation files
|
|
|
|
* (the "Software"), to deal in the Software without restriction,
|
|
|
|
* including without limitation the rights to use, copy, modify, merge,
|
|
|
|
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
|
|
* and to permit persons to whom the Software is furnished to do so,
|
|
|
|
* subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice (including the
|
|
|
|
* next paragraph) shall be included in all copies or substantial
|
|
|
|
* portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
|
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
|
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
* SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _INTEL_HDMI_AUDIO_H_
|
|
|
|
#define _INTEL_HDMI_AUDIO_H_
|
|
|
|
|
|
|
|
#include "intel_hdmi_lpe_audio.h"
|
|
|
|
|
|
|
|
#define MAX_PB_STREAMS 1
|
|
|
|
#define MAX_CAP_STREAMS 0
|
|
|
|
#define BYTES_PER_WORD 0x4
|
2017-02-07 19:17:23 +08:00
|
|
|
#define INTEL_HAD "HdmiLpeAudio"
|
|
|
|
|
|
|
|
/*
|
|
|
|
* CEA speaker placement:
|
|
|
|
*
|
|
|
|
* FL FLC FC FRC FR
|
|
|
|
*
|
|
|
|
* LFE
|
|
|
|
*
|
|
|
|
* RL RLC RC RRC RR
|
|
|
|
*
|
|
|
|
* The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M
|
|
|
|
* corresponds to CEA RL/RR; The SMPTE channel _assignment_ C/LFE is
|
|
|
|
* swapped to CEA LFE/FC.
|
|
|
|
*/
|
|
|
|
enum cea_speaker_placement {
|
|
|
|
FL = (1 << 0), /* Front Left */
|
|
|
|
FC = (1 << 1), /* Front Center */
|
|
|
|
FR = (1 << 2), /* Front Right */
|
|
|
|
FLC = (1 << 3), /* Front Left Center */
|
|
|
|
FRC = (1 << 4), /* Front Right Center */
|
|
|
|
RL = (1 << 5), /* Rear Left */
|
|
|
|
RC = (1 << 6), /* Rear Center */
|
|
|
|
RR = (1 << 7), /* Rear Right */
|
|
|
|
RLC = (1 << 8), /* Rear Left Center */
|
|
|
|
RRC = (1 << 9), /* Rear Right Center */
|
|
|
|
LFE = (1 << 10), /* Low Frequency Effect */
|
|
|
|
};
|
2017-01-25 06:57:52 +08:00
|
|
|
|
2017-02-07 19:17:23 +08:00
|
|
|
struct cea_channel_speaker_allocation {
|
|
|
|
int ca_index;
|
|
|
|
int speakers[8];
|
2017-01-25 06:57:52 +08:00
|
|
|
|
2017-02-07 19:17:23 +08:00
|
|
|
/* derived values, just for convenience */
|
|
|
|
int channels;
|
|
|
|
int spk_mask;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct channel_map_table {
|
|
|
|
unsigned char map; /* ALSA API channel map position */
|
|
|
|
unsigned char cea_slot; /* CEA slot value */
|
|
|
|
int spk_mask; /* speaker position bit mask */
|
|
|
|
};
|
2017-01-25 06:57:52 +08:00
|
|
|
|
|
|
|
struct pcm_stream_info {
|
2017-02-02 20:00:12 +08:00
|
|
|
struct snd_pcm_substream *substream;
|
|
|
|
int substream_refcount;
|
2017-01-25 06:57:52 +08:00
|
|
|
};
|
|
|
|
|
2017-02-02 23:19:03 +08:00
|
|
|
/*
|
2017-01-25 06:57:52 +08:00
|
|
|
* struct snd_intelhad - intelhad driver structure
|
|
|
|
*
|
|
|
|
* @card: ptr to hold card details
|
2017-02-03 00:46:49 +08:00
|
|
|
* @connected: the monitor connection status
|
2017-01-25 06:57:52 +08:00
|
|
|
* @stream_info: stream information
|
2017-01-31 20:52:22 +08:00
|
|
|
* @eld: holds ELD info
|
2017-01-25 06:57:52 +08:00
|
|
|
* @curr_buf: pointer to hold current active ring buf
|
|
|
|
* @valid_buf_cnt: ring buffer count for stream
|
|
|
|
* @had_spinlock: driver lock
|
|
|
|
* @aes_bits: IEC958 status bits
|
|
|
|
* @buff_done: id of current buffer done intr
|
|
|
|
* @dev: platoform device handle
|
|
|
|
* @chmap: holds channel map info
|
|
|
|
*/
|
|
|
|
struct snd_intelhad {
|
2017-04-28 00:02:29 +08:00
|
|
|
struct snd_intelhad_card *card_ctx;
|
2017-02-03 00:46:49 +08:00
|
|
|
bool connected;
|
2017-01-25 06:57:52 +08:00
|
|
|
struct pcm_stream_info stream_info;
|
2017-02-02 22:37:11 +08:00
|
|
|
unsigned char eld[HDMI_MAX_ELD_BYTES];
|
2017-02-01 04:16:52 +08:00
|
|
|
bool dp_output;
|
2017-01-25 06:57:52 +08:00
|
|
|
unsigned int aes_bits;
|
|
|
|
spinlock_t had_spinlock;
|
|
|
|
struct device *dev;
|
|
|
|
struct snd_pcm_chmap *chmap;
|
2017-01-31 20:52:22 +08:00
|
|
|
int tmds_clock_speed;
|
|
|
|
int link_rate;
|
2017-04-28 00:02:30 +08:00
|
|
|
int port; /* fixed */
|
|
|
|
int pipe; /* can change dynamically */
|
2017-01-31 20:52:22 +08:00
|
|
|
|
ALSA: x86: Refactor PCM process engine
This is again a big rewrite of the driver; now it touches the code to
process PCM stream transfers.
The most fundamental change is that the driver may support more than
four periods. Instead of keeping the same index between both the ring
buffer (with the fixed four buffer descriptors) and the PCM buffer
periods, we keep difference indices for both (bd_head and pcm_head
fields). In addition, when the periods are more than four, we need to
track both head and next indices. That is, we now have three indices:
bd_head, pcm_head and pcm_filled.
Also, the driver works better for periods < 4, too: the remaining BDs
out of four are marked as invalid, so that the hardware skips those
BDs in its loop.
By this flexibility, we can use even ALSA-lib dmix plugin, which
requires 16 periods as default.
The buffer size could be up to 20bit, so the max buffer size was
increased accordingly. However, the buffer pre-allocation is kept as
the old value (600kB) as default. The reason is the limited number of
BDs: since it doesn't suffice for the useful SG page management that
can fit with the usual page allocator like some other drivers, we have
to still allocate continuous pages, hence we shouldn't take too big
memories there.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-02-03 07:01:18 +08:00
|
|
|
/* ring buffer (BD) position index */
|
|
|
|
unsigned int bd_head;
|
|
|
|
/* PCM buffer position indices */
|
|
|
|
unsigned int pcmbuf_head; /* being processed */
|
|
|
|
unsigned int pcmbuf_filled; /* to be filled */
|
|
|
|
|
|
|
|
unsigned int num_bds; /* number of BDs */
|
|
|
|
unsigned int period_bytes; /* PCM period size in bytes */
|
|
|
|
|
2017-01-31 20:52:22 +08:00
|
|
|
/* internal stuff */
|
2017-02-07 23:17:06 +08:00
|
|
|
union aud_cfg aud_config; /* AUD_CONFIG reg value cache */
|
2017-01-31 20:52:22 +08:00
|
|
|
struct work_struct hdmi_audio_wq;
|
2017-02-02 00:53:19 +08:00
|
|
|
struct mutex mutex; /* for protecting chmap and eld */
|
2017-02-11 15:21:56 +08:00
|
|
|
bool need_reset;
|
2017-02-14 19:29:38 +08:00
|
|
|
struct snd_jack *jack;
|
2017-01-25 06:57:52 +08:00
|
|
|
};
|
|
|
|
|
2017-04-28 00:02:29 +08:00
|
|
|
struct snd_intelhad_card {
|
|
|
|
struct snd_card *card;
|
|
|
|
struct device *dev;
|
|
|
|
|
|
|
|
/* internal stuff */
|
|
|
|
int irq;
|
|
|
|
void __iomem *mmio_start;
|
2017-04-28 00:02:30 +08:00
|
|
|
int num_pipes;
|
2017-04-28 00:02:29 +08:00
|
|
|
int num_ports;
|
2017-04-28 00:02:30 +08:00
|
|
|
struct snd_intelhad pcm_ctx[3]; /* one for each port */
|
2017-04-28 00:02:29 +08:00
|
|
|
};
|
|
|
|
|
2017-01-25 06:57:52 +08:00
|
|
|
#endif /* _INTEL_HDMI_AUDIO_ */
|