aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2016-09-26 11:59:50 -0400
committerMark Brown <broonie@kernel.org>2016-09-26 11:59:50 -0400
commit88b456b0f4a2a4c10c141a7d83113a8ce2164463 (patch)
tree308cce76ad8a63a1507d1effa971c9fea48806bc /sound
parent2d995e5dc283adbfbf9c1eb81bf35ca7af2d22a6 (diff)
ASoC: hdac_hdmi: Drop use of audio component framework to read ELD
The audio component framework code has not yet landed in the i915 driver so drop the use of the API for the time being. Signed-off-by: Mark Brown <broonie@kernel.org> Cc: Jeeja KP <jeeja.kp@intel.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/hdac_hdmi.c201
1 files changed, 145 insertions, 56 deletions
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 537f61aa27fa..4e181b270d95 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -46,10 +46,6 @@
46#define ELD_MAX_SIZE 256 46#define ELD_MAX_SIZE 256
47#define ELD_FIXED_BYTES 20 47#define ELD_FIXED_BYTES 20
48 48
49#define ELD_VER_CEA_861D 2
50#define ELD_VER_PARTIAL 31
51#define ELD_MAX_MNL 16
52
53struct hdac_hdmi_cvt_params { 49struct hdac_hdmi_cvt_params {
54 unsigned int channels_min; 50 unsigned int channels_min;
55 unsigned int channels_max; 51 unsigned int channels_max;
@@ -85,6 +81,8 @@ struct hdac_hdmi_pin {
85 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS]; 81 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
86 struct hdac_hdmi_eld eld; 82 struct hdac_hdmi_eld eld;
87 struct hdac_ext_device *edev; 83 struct hdac_ext_device *edev;
84 int repoll_count;
85 struct delayed_work work;
88 struct mutex lock; 86 struct mutex lock;
89 bool chmap_set; 87 bool chmap_set;
90 unsigned char chmap[8]; /* ALSA API channel-map */ 88 unsigned char chmap[8]; /* ALSA API channel-map */
@@ -175,6 +173,80 @@ format_constraint:
175 173
176} 174}
177 175
176 /* HDMI ELD routines */
177static unsigned int hdac_hdmi_get_eld_data(struct hdac_device *codec,
178 hda_nid_t nid, int byte_index)
179{
180 unsigned int val;
181
182 val = snd_hdac_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_ELDD,
183 byte_index);
184
185 dev_dbg(&codec->dev, "HDMI: ELD data byte %d: 0x%x\n",
186 byte_index, val);
187
188 return val;
189}
190
191static int hdac_hdmi_get_eld_size(struct hdac_device *codec, hda_nid_t nid)
192{
193 return snd_hdac_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
194 AC_DIPSIZE_ELD_BUF);
195}
196
197/*
198 * This function queries the ELD size and ELD data and fills in the buffer
199 * passed by user
200 */
201static int hdac_hdmi_get_eld(struct hdac_device *codec, hda_nid_t nid,
202 unsigned char *buf, int *eld_size)
203{
204 int i, size, ret = 0;
205
206 /*
207 * ELD size is initialized to zero in caller function. If no errors and
208 * ELD is valid, actual eld_size is assigned.
209 */
210
211 size = hdac_hdmi_get_eld_size(codec, nid);
212 if (size < ELD_FIXED_BYTES || size > ELD_MAX_SIZE) {
213 dev_err(&codec->dev, "HDMI: invalid ELD buf size %d\n", size);
214 return -ERANGE;
215 }
216
217 /* set ELD buffer */
218 for (i = 0; i < size; i++) {
219 unsigned int val = hdac_hdmi_get_eld_data(codec, nid, i);
220 /*
221 * Graphics driver might be writing to ELD buffer right now.
222 * Just abort. The caller will repoll after a while.
223 */
224 if (!(val & AC_ELDD_ELD_VALID)) {
225 dev_err(&codec->dev,
226 "HDMI: invalid ELD data byte %d\n", i);
227 ret = -EINVAL;
228 goto error;
229 }
230 val &= AC_ELDD_ELD_DATA;
231 /*
232 * The first byte cannot be zero. This can happen on some DVI
233 * connections. Some Intel chips may also need some 250ms delay
234 * to return non-zero ELD data, even when the graphics driver
235 * correctly writes ELD content before setting ELD_valid bit.
236 */
237 if (!val && !i) {
238 dev_err(&codec->dev, "HDMI: 0 ELD data\n");
239 ret = -EINVAL;
240 goto error;
241 }
242 buf[i] = val;
243 }
244
245 *eld_size = size;
246error:
247 return ret;
248}
249
178static int hdac_hdmi_setup_stream(struct hdac_ext_device *hdac, 250static int hdac_hdmi_setup_stream(struct hdac_ext_device *hdac,
179 hda_nid_t cvt_nid, hda_nid_t pin_nid, 251 hda_nid_t cvt_nid, hda_nid_t pin_nid,
180 u32 stream_tag, int format) 252 u32 stream_tag, int format)
@@ -987,59 +1059,32 @@ static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid)
987 return hdac_hdmi_query_cvt_params(&edev->hdac, cvt); 1059 return hdac_hdmi_query_cvt_params(&edev->hdac, cvt);
988} 1060}
989 1061
990static int hdac_hdmi_parse_eld(struct hdac_ext_device *edev, 1062static void hdac_hdmi_parse_eld(struct hdac_ext_device *edev,
991 struct hdac_hdmi_pin *pin) 1063 struct hdac_hdmi_pin *pin)
992{ 1064{
993 unsigned int ver, mnl;
994
995 ver = (pin->eld.eld_buffer[DRM_ELD_VER] & DRM_ELD_VER_MASK)
996 >> DRM_ELD_VER_SHIFT;
997
998 if (ver != ELD_VER_CEA_861D && ver != ELD_VER_PARTIAL) {
999 dev_dbg(&edev->hdac.dev, "HDMI: Unknown ELD version %d\n", ver);
1000 return -EINVAL;
1001 }
1002
1003 mnl = (pin->eld.eld_buffer[DRM_ELD_CEA_EDID_VER_MNL] &
1004 DRM_ELD_MNL_MASK) >> DRM_ELD_MNL_SHIFT;
1005
1006 if (mnl > ELD_MAX_MNL) {
1007 dev_dbg(&edev->hdac.dev, "HDMI: MNL Invalid %d\n", mnl);
1008 return -EINVAL;
1009 }
1010
1011 pin->eld.info.spk_alloc = pin->eld.eld_buffer[DRM_ELD_SPEAKER]; 1065 pin->eld.info.spk_alloc = pin->eld.eld_buffer[DRM_ELD_SPEAKER];
1012
1013 return 0;
1014} 1066}
1015 1067
1016static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin) 1068static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, int repoll)
1017{ 1069{
1018 struct hdac_ext_device *edev = pin->edev; 1070 struct hdac_ext_device *edev = pin->edev;
1019 struct hdac_hdmi_priv *hdmi = edev->private_data; 1071 struct hdac_hdmi_priv *hdmi = edev->private_data;
1020 struct hdac_hdmi_pcm *pcm; 1072 struct hdac_hdmi_pcm *pcm;
1021 int size; 1073 int val;
1022 1074
1023 mutex_lock(&hdmi->pin_mutex); 1075 pin->repoll_count = repoll;
1024 pin->eld.monitor_present = false;
1025 1076
1026 size = snd_hdac_acomp_get_eld(&edev->hdac, pin->nid, -1, 1077 pm_runtime_get_sync(&edev->hdac.dev);
1027 &pin->eld.monitor_present, pin->eld.eld_buffer, 1078 val = snd_hdac_codec_read(&edev->hdac, pin->nid, 0,
1028 ELD_MAX_SIZE); 1079 AC_VERB_GET_PIN_SENSE, 0);
1029 1080
1030 if (size > 0) { 1081 dev_dbg(&edev->hdac.dev, "Pin sense val %x for pin: %d\n",
1031 size = min(size, ELD_MAX_SIZE); 1082 val, pin->nid);
1032 if (hdac_hdmi_parse_eld(edev, pin) < 0)
1033 size = -EINVAL;
1034 }
1035 1083
1036 if (size > 0) { 1084
1037 pin->eld.eld_valid = true; 1085 mutex_lock(&hdmi->pin_mutex);
1038 pin->eld.eld_size = size; 1086 pin->eld.monitor_present = !!(val & AC_PINSENSE_PRESENCE);
1039 } else { 1087 pin->eld.eld_valid = !!(val & AC_PINSENSE_ELDV);
1040 pin->eld.eld_valid = false;
1041 pin->eld.eld_size = 0;
1042 }
1043 1088
1044 pcm = hdac_hdmi_get_pcm(edev, pin); 1089 pcm = hdac_hdmi_get_pcm(edev, pin);
1045 1090
@@ -1061,23 +1106,66 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin)
1061 } 1106 }
1062 1107
1063 mutex_unlock(&hdmi->pin_mutex); 1108 mutex_unlock(&hdmi->pin_mutex);
1064 return; 1109 goto put_hdac_device;
1065 } 1110 }
1066 1111
1067 if (pin->eld.monitor_present && pin->eld.eld_valid) { 1112 if (pin->eld.monitor_present && pin->eld.eld_valid) {
1068 if (pcm) { 1113 /* TODO: use i915 component for reading ELD later */
1069 dev_dbg(&edev->hdac.dev, 1114 if (hdac_hdmi_get_eld(&edev->hdac, pin->nid,
1070 "jack report for pcm=%d\n", 1115 pin->eld.eld_buffer,
1071 pcm->pcm_id); 1116 &pin->eld.eld_size) == 0) {
1072 1117
1073 snd_jack_report(pcm->jack, SND_JACK_AVOUT); 1118 if (pcm) {
1074 } 1119 dev_dbg(&edev->hdac.dev,
1120 "jack report for pcm=%d\n",
1121 pcm->pcm_id);
1122
1123 snd_jack_report(pcm->jack, SND_JACK_AVOUT);
1124 }
1125 hdac_hdmi_parse_eld(edev, pin);
1126
1127 print_hex_dump_debug("ELD: ",
1128 DUMP_PREFIX_OFFSET, 16, 1,
1129 pin->eld.eld_buffer, pin->eld.eld_size,
1130 true);
1131 } else {
1132 pin->eld.monitor_present = false;
1133 pin->eld.eld_valid = false;
1134
1135 if (pcm) {
1136 dev_dbg(&edev->hdac.dev,
1137 "jack report for pcm=%d\n",
1138 pcm->pcm_id);
1075 1139
1076 print_hex_dump_debug("ELD: ", DUMP_PREFIX_OFFSET, 16, 1, 1140 snd_jack_report(pcm->jack, 0);
1077 pin->eld.eld_buffer, pin->eld.eld_size, false); 1141 }
1142 }
1078 } 1143 }
1079 1144
1080 mutex_unlock(&hdmi->pin_mutex); 1145 mutex_unlock(&hdmi->pin_mutex);
1146
1147 /*
1148 * Sometimes the pin_sense may present invalid monitor
1149 * present and eld_valid. If ELD data is not valid, loop few
1150 * more times to get correct pin sense and valid ELD.
1151 */
1152 if ((!pin->eld.monitor_present || !pin->eld.eld_valid) && repoll)
1153 schedule_delayed_work(&pin->work, msecs_to_jiffies(300));
1154
1155put_hdac_device:
1156 pm_runtime_put_sync(&edev->hdac.dev);
1157}
1158
1159static void hdac_hdmi_repoll_eld(struct work_struct *work)
1160{
1161 struct hdac_hdmi_pin *pin =
1162 container_of(to_delayed_work(work), struct hdac_hdmi_pin, work);
1163
1164 /* picked from legacy HDA driver */
1165 if (pin->repoll_count++ > 6)
1166 pin->repoll_count = 0;
1167
1168 hdac_hdmi_present_sense(pin, pin->repoll_count);
1081} 1169}
1082 1170
1083static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid) 1171static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
@@ -1096,6 +1184,7 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
1096 1184
1097 pin->edev = edev; 1185 pin->edev = edev;
1098 mutex_init(&pin->lock); 1186 mutex_init(&pin->lock);
1187 INIT_DELAYED_WORK(&pin->work, hdac_hdmi_repoll_eld);
1099 1188
1100 return 0; 1189 return 0;
1101} 1190}
@@ -1306,7 +1395,7 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port)
1306 1395
1307 list_for_each_entry(pin, &hdmi->pin_list, head) { 1396 list_for_each_entry(pin, &hdmi->pin_list, head) {
1308 if (pin->nid == pin_nid) 1397 if (pin->nid == pin_nid)
1309 hdac_hdmi_present_sense(pin); 1398 hdac_hdmi_present_sense(pin, 1);
1310 } 1399 }
1311} 1400}
1312 1401
@@ -1407,7 +1496,7 @@ static int hdmi_codec_probe(struct snd_soc_codec *codec)
1407 } 1496 }
1408 1497
1409 list_for_each_entry(pin, &hdmi->pin_list, head) 1498 list_for_each_entry(pin, &hdmi->pin_list, head)
1410 hdac_hdmi_present_sense(pin); 1499 hdac_hdmi_present_sense(pin, 1);
1411 1500
1412 /* Imp: Store the card pointer in hda_codec */ 1501 /* Imp: Store the card pointer in hda_codec */
1413 edev->card = dapm->card->snd_card; 1502 edev->card = dapm->card->snd_card;
@@ -1472,7 +1561,7 @@ static void hdmi_codec_complete(struct device *dev)
1472 * all pins here. 1561 * all pins here.
1473 */ 1562 */
1474 list_for_each_entry(pin, &hdmi->pin_list, head) 1563 list_for_each_entry(pin, &hdmi->pin_list, head)
1475 hdac_hdmi_present_sense(pin); 1564 hdac_hdmi_present_sense(pin, 1);
1476 1565
1477 pm_runtime_put_sync(&edev->hdac.dev); 1566 pm_runtime_put_sync(&edev->hdac.dev);
1478} 1567}