1/*
2 * Regmap support for HD-audio verbs
3 *
4 * A virtual register is translated to one or more hda verbs for write,
5 * vice versa for read.
6 *
7 * A few limitations:
8 * - Provided for not all verbs but only subset standard non-volatile verbs.
9 * - For reading, only AC_VERB_GET_* variants can be used.
10 * - For writing, mapped to the *corresponding* AC_VERB_SET_* variants,
11 *   so can't handle asymmetric verbs for read and write
12 */
13
14#include <linux/slab.h>
15#include <linux/device.h>
16#include <linux/regmap.h>
17#include <linux/export.h>
18#include <linux/pm.h>
19#include <linux/pm_runtime.h>
20#include <sound/core.h>
21#include <sound/hdaudio.h>
22#include <sound/hda_regmap.h>
23
24#ifdef CONFIG_PM
25#define codec_is_running(codec)				\
26	(atomic_read(&(codec)->in_pm) ||		\
27	 !pm_runtime_suspended(&(codec)->dev))
28#else
29#define codec_is_running(codec)		true
30#endif
31
32#define get_verb(reg)	(((reg) >> 8) & 0xfff)
33
34static bool hda_volatile_reg(struct device *dev, unsigned int reg)
35{
36	struct hdac_device *codec = dev_to_hdac_dev(dev);
37	unsigned int verb = get_verb(reg);
38
39	switch (verb) {
40	case AC_VERB_GET_PROC_COEF:
41		return !codec->cache_coef;
42	case AC_VERB_GET_COEF_INDEX:
43	case AC_VERB_GET_PROC_STATE:
44	case AC_VERB_GET_POWER_STATE:
45	case AC_VERB_GET_PIN_SENSE:
46	case AC_VERB_GET_HDMI_DIP_SIZE:
47	case AC_VERB_GET_HDMI_ELDD:
48	case AC_VERB_GET_HDMI_DIP_INDEX:
49	case AC_VERB_GET_HDMI_DIP_DATA:
50	case AC_VERB_GET_HDMI_DIP_XMIT:
51	case AC_VERB_GET_HDMI_CP_CTRL:
52	case AC_VERB_GET_HDMI_CHAN_SLOT:
53	case AC_VERB_GET_DEVICE_SEL:
54	case AC_VERB_GET_DEVICE_LIST:	/* read-only volatile */
55		return true;
56	}
57
58	return false;
59}
60
61static bool hda_writeable_reg(struct device *dev, unsigned int reg)
62{
63	struct hdac_device *codec = dev_to_hdac_dev(dev);
64	unsigned int verb = get_verb(reg);
65	int i;
66
67	for (i = 0; i < codec->vendor_verbs.used; i++) {
68		unsigned int *v = snd_array_elem(&codec->vendor_verbs, i);
69		if (verb == *v)
70			return true;
71	}
72
73	if (codec->caps_overwriting)
74		return true;
75
76	switch (verb & 0xf00) {
77	case AC_VERB_GET_STREAM_FORMAT:
78	case AC_VERB_GET_AMP_GAIN_MUTE:
79		return true;
80	case AC_VERB_GET_PROC_COEF:
81		return codec->cache_coef;
82	case 0xf00:
83		break;
84	default:
85		return false;
86	}
87
88	switch (verb) {
89	case AC_VERB_GET_CONNECT_SEL:
90	case AC_VERB_GET_SDI_SELECT:
91	case AC_VERB_GET_PIN_WIDGET_CONTROL:
92	case AC_VERB_GET_UNSOLICITED_RESPONSE: /* only as SET_UNSOLICITED_ENABLE */
93	case AC_VERB_GET_BEEP_CONTROL:
94	case AC_VERB_GET_EAPD_BTLENABLE:
95	case AC_VERB_GET_DIGI_CONVERT_1:
96	case AC_VERB_GET_DIGI_CONVERT_2: /* only for beep control */
97	case AC_VERB_GET_VOLUME_KNOB_CONTROL:
98	case AC_VERB_GET_GPIO_MASK:
99	case AC_VERB_GET_GPIO_DIRECTION:
100	case AC_VERB_GET_GPIO_DATA: /* not for volatile read */
101	case AC_VERB_GET_GPIO_WAKE_MASK:
102	case AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK:
103	case AC_VERB_GET_GPIO_STICKY_MASK:
104		return true;
105	}
106
107	return false;
108}
109
110static bool hda_readable_reg(struct device *dev, unsigned int reg)
111{
112	struct hdac_device *codec = dev_to_hdac_dev(dev);
113	unsigned int verb = get_verb(reg);
114
115	if (codec->caps_overwriting)
116		return true;
117
118	switch (verb) {
119	case AC_VERB_PARAMETERS:
120	case AC_VERB_GET_CONNECT_LIST:
121	case AC_VERB_GET_SUBSYSTEM_ID:
122		return true;
123	/* below are basically writable, but disabled for reducing unnecessary
124	 * writes at sync
125	 */
126	case AC_VERB_GET_CONFIG_DEFAULT: /* usually just read */
127	case AC_VERB_GET_CONV: /* managed in PCM code */
128	case AC_VERB_GET_CVT_CHAN_COUNT: /* managed in HDMI CA code */
129		return true;
130	}
131
132	return hda_writeable_reg(dev, reg);
133}
134
135/*
136 * Stereo amp pseudo register:
137 * for making easier to handle the stereo volume control, we provide a
138 * fake register to deal both left and right channels by a single
139 * (pseudo) register access.  A verb consisting of SET_AMP_GAIN with
140 * *both* SET_LEFT and SET_RIGHT bits takes a 16bit value, the lower 8bit
141 * for the left and the upper 8bit for the right channel.
142 */
143static bool is_stereo_amp_verb(unsigned int reg)
144{
145	if (((reg >> 8) & 0x700) != AC_VERB_SET_AMP_GAIN_MUTE)
146		return false;
147	return (reg & (AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT)) ==
148		(AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT);
149}
150
151/* read a pseudo stereo amp register (16bit left+right) */
152static int hda_reg_read_stereo_amp(struct hdac_device *codec,
153				   unsigned int reg, unsigned int *val)
154{
155	unsigned int left, right;
156	int err;
157
158	reg &= ~(AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT);
159	err = snd_hdac_exec_verb(codec, reg | AC_AMP_GET_LEFT, 0, &left);
160	if (err < 0)
161		return err;
162	err = snd_hdac_exec_verb(codec, reg | AC_AMP_GET_RIGHT, 0, &right);
163	if (err < 0)
164		return err;
165	*val = left | (right << 8);
166	return 0;
167}
168
169/* write a pseudo stereo amp register (16bit left+right) */
170static int hda_reg_write_stereo_amp(struct hdac_device *codec,
171				    unsigned int reg, unsigned int val)
172{
173	int err;
174	unsigned int verb, left, right;
175
176	verb = AC_VERB_SET_AMP_GAIN_MUTE << 8;
177	if (reg & AC_AMP_GET_OUTPUT)
178		verb |= AC_AMP_SET_OUTPUT;
179	else
180		verb |= AC_AMP_SET_INPUT | ((reg & 0xf) << 8);
181	reg = (reg & ~0xfffff) | verb;
182
183	left = val & 0xff;
184	right = (val >> 8) & 0xff;
185	if (left == right) {
186		reg |= AC_AMP_SET_LEFT | AC_AMP_SET_RIGHT;
187		return snd_hdac_exec_verb(codec, reg | left, 0, NULL);
188	}
189
190	err = snd_hdac_exec_verb(codec, reg | AC_AMP_SET_LEFT | left, 0, NULL);
191	if (err < 0)
192		return err;
193	err = snd_hdac_exec_verb(codec, reg | AC_AMP_SET_RIGHT | right, 0, NULL);
194	if (err < 0)
195		return err;
196	return 0;
197}
198
199/* read a pseudo coef register (16bit) */
200static int hda_reg_read_coef(struct hdac_device *codec, unsigned int reg,
201			     unsigned int *val)
202{
203	unsigned int verb;
204	int err;
205
206	if (!codec->cache_coef)
207		return -EINVAL;
208	/* LSB 8bit = coef index */
209	verb = (reg & ~0xfff00) | (AC_VERB_SET_COEF_INDEX << 8);
210	err = snd_hdac_exec_verb(codec, verb, 0, NULL);
211	if (err < 0)
212		return err;
213	verb = (reg & ~0xfffff) | (AC_VERB_GET_COEF_INDEX << 8);
214	return snd_hdac_exec_verb(codec, verb, 0, val);
215}
216
217/* write a pseudo coef register (16bit) */
218static int hda_reg_write_coef(struct hdac_device *codec, unsigned int reg,
219			      unsigned int val)
220{
221	unsigned int verb;
222	int err;
223
224	if (!codec->cache_coef)
225		return -EINVAL;
226	/* LSB 8bit = coef index */
227	verb = (reg & ~0xfff00) | (AC_VERB_SET_COEF_INDEX << 8);
228	err = snd_hdac_exec_verb(codec, verb, 0, NULL);
229	if (err < 0)
230		return err;
231	verb = (reg & ~0xfffff) | (AC_VERB_GET_COEF_INDEX << 8) |
232		(val & 0xffff);
233	return snd_hdac_exec_verb(codec, verb, 0, NULL);
234}
235
236static int hda_reg_read(void *context, unsigned int reg, unsigned int *val)
237{
238	struct hdac_device *codec = context;
239	int verb = get_verb(reg);
240	int err;
241
242	if (!codec_is_running(codec) && verb != AC_VERB_GET_POWER_STATE)
243		return -EAGAIN;
244	reg |= (codec->addr << 28);
245	if (is_stereo_amp_verb(reg))
246		return hda_reg_read_stereo_amp(codec, reg, val);
247	if (verb == AC_VERB_GET_PROC_COEF)
248		return hda_reg_read_coef(codec, reg, val);
249	if ((verb & 0x700) == AC_VERB_SET_AMP_GAIN_MUTE)
250		reg &= ~AC_AMP_FAKE_MUTE;
251
252	err = snd_hdac_exec_verb(codec, reg, 0, val);
253	if (err < 0)
254		return err;
255	/* special handling for asymmetric reads */
256	if (verb == AC_VERB_GET_POWER_STATE) {
257		if (*val & AC_PWRST_ERROR)
258			*val = -1;
259		else /* take only the actual state */
260			*val = (*val >> 4) & 0x0f;
261	}
262	return 0;
263}
264
265static int hda_reg_write(void *context, unsigned int reg, unsigned int val)
266{
267	struct hdac_device *codec = context;
268	unsigned int verb;
269	int i, bytes, err;
270
271	if (codec->caps_overwriting)
272		return 0;
273
274	reg &= ~0x00080000U; /* drop GET bit */
275	reg |= (codec->addr << 28);
276	verb = get_verb(reg);
277
278	if (!codec_is_running(codec) && verb != AC_VERB_SET_POWER_STATE)
279		return codec->lazy_cache ? 0 : -EAGAIN;
280
281	if (is_stereo_amp_verb(reg))
282		return hda_reg_write_stereo_amp(codec, reg, val);
283
284	if (verb == AC_VERB_SET_PROC_COEF)
285		return hda_reg_write_coef(codec, reg, val);
286
287	switch (verb & 0xf00) {
288	case AC_VERB_SET_AMP_GAIN_MUTE:
289		if ((reg & AC_AMP_FAKE_MUTE) && (val & AC_AMP_MUTE))
290			val = 0;
291		verb = AC_VERB_SET_AMP_GAIN_MUTE;
292		if (reg & AC_AMP_GET_LEFT)
293			verb |= AC_AMP_SET_LEFT >> 8;
294		else
295			verb |= AC_AMP_SET_RIGHT >> 8;
296		if (reg & AC_AMP_GET_OUTPUT) {
297			verb |= AC_AMP_SET_OUTPUT >> 8;
298		} else {
299			verb |= AC_AMP_SET_INPUT >> 8;
300			verb |= reg & 0xf;
301		}
302		break;
303	}
304
305	switch (verb) {
306	case AC_VERB_SET_DIGI_CONVERT_1:
307		bytes = 2;
308		break;
309	case AC_VERB_SET_CONFIG_DEFAULT_BYTES_0:
310		bytes = 4;
311		break;
312	default:
313		bytes = 1;
314		break;
315	}
316
317	for (i = 0; i < bytes; i++) {
318		reg &= ~0xfffff;
319		reg |= (verb + i) << 8 | ((val >> (8 * i)) & 0xff);
320		err = snd_hdac_exec_verb(codec, reg, 0, NULL);
321		if (err < 0)
322			return err;
323	}
324
325	return 0;
326}
327
328static const struct regmap_config hda_regmap_cfg = {
329	.name = "hdaudio",
330	.reg_bits = 32,
331	.val_bits = 32,
332	.max_register = 0xfffffff,
333	.writeable_reg = hda_writeable_reg,
334	.readable_reg = hda_readable_reg,
335	.volatile_reg = hda_volatile_reg,
336	.cache_type = REGCACHE_RBTREE,
337	.reg_read = hda_reg_read,
338	.reg_write = hda_reg_write,
339	.use_single_rw = true,
340};
341
342int snd_hdac_regmap_init(struct hdac_device *codec)
343{
344	struct regmap *regmap;
345
346	regmap = regmap_init(&codec->dev, NULL, codec, &hda_regmap_cfg);
347	if (IS_ERR(regmap))
348		return PTR_ERR(regmap);
349	codec->regmap = regmap;
350	snd_array_init(&codec->vendor_verbs, sizeof(unsigned int), 8);
351	return 0;
352}
353EXPORT_SYMBOL_GPL(snd_hdac_regmap_init);
354
355void snd_hdac_regmap_exit(struct hdac_device *codec)
356{
357	if (codec->regmap) {
358		regmap_exit(codec->regmap);
359		codec->regmap = NULL;
360		snd_array_free(&codec->vendor_verbs);
361	}
362}
363EXPORT_SYMBOL_GPL(snd_hdac_regmap_exit);
364
365/**
366 * snd_hdac_regmap_add_vendor_verb - add a vendor-specific verb to regmap
367 * @codec: the codec object
368 * @verb: verb to allow accessing via regmap
369 *
370 * Returns zero for success or a negative error code.
371 */
372int snd_hdac_regmap_add_vendor_verb(struct hdac_device *codec,
373				    unsigned int verb)
374{
375	unsigned int *p = snd_array_new(&codec->vendor_verbs);
376
377	if (!p)
378		return -ENOMEM;
379	*p = verb | 0x800; /* set GET bit */
380	return 0;
381}
382EXPORT_SYMBOL_GPL(snd_hdac_regmap_add_vendor_verb);
383
384/*
385 * helper functions
386 */
387
388/* write a pseudo-register value (w/o power sequence) */
389static int reg_raw_write(struct hdac_device *codec, unsigned int reg,
390			 unsigned int val)
391{
392	if (!codec->regmap)
393		return hda_reg_write(codec, reg, val);
394	else
395		return regmap_write(codec->regmap, reg, val);
396}
397
398/**
399 * snd_hdac_regmap_write_raw - write a pseudo register with power mgmt
400 * @codec: the codec object
401 * @reg: pseudo register
402 * @val: value to write
403 *
404 * Returns zero if successful or a negative error code.
405 */
406int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
407			      unsigned int val)
408{
409	int err;
410
411	err = reg_raw_write(codec, reg, val);
412	if (err == -EAGAIN) {
413		err = snd_hdac_power_up_pm(codec);
414		if (!err)
415			err = reg_raw_write(codec, reg, val);
416		snd_hdac_power_down_pm(codec);
417	}
418	return err;
419}
420EXPORT_SYMBOL_GPL(snd_hdac_regmap_write_raw);
421
422static int reg_raw_read(struct hdac_device *codec, unsigned int reg,
423			unsigned int *val)
424{
425	if (!codec->regmap)
426		return hda_reg_read(codec, reg, val);
427	else
428		return regmap_read(codec->regmap, reg, val);
429}
430
431/**
432 * snd_hdac_regmap_read_raw - read a pseudo register with power mgmt
433 * @codec: the codec object
434 * @reg: pseudo register
435 * @val: pointer to store the read value
436 *
437 * Returns zero if successful or a negative error code.
438 */
439int snd_hdac_regmap_read_raw(struct hdac_device *codec, unsigned int reg,
440			     unsigned int *val)
441{
442	int err;
443
444	err = reg_raw_read(codec, reg, val);
445	if (err == -EAGAIN) {
446		err = snd_hdac_power_up_pm(codec);
447		if (!err)
448			err = reg_raw_read(codec, reg, val);
449		snd_hdac_power_down_pm(codec);
450	}
451	return err;
452}
453EXPORT_SYMBOL_GPL(snd_hdac_regmap_read_raw);
454
455/**
456 * snd_hdac_regmap_update_raw - update a pseudo register with power mgmt
457 * @codec: the codec object
458 * @reg: pseudo register
459 * @mask: bit mask to udpate
460 * @val: value to update
461 *
462 * Returns zero if successful or a negative error code.
463 */
464int snd_hdac_regmap_update_raw(struct hdac_device *codec, unsigned int reg,
465			       unsigned int mask, unsigned int val)
466{
467	unsigned int orig;
468	int err;
469
470	val &= mask;
471	err = snd_hdac_regmap_read_raw(codec, reg, &orig);
472	if (err < 0)
473		return err;
474	val |= orig & ~mask;
475	if (val == orig)
476		return 0;
477	err = snd_hdac_regmap_write_raw(codec, reg, val);
478	if (err < 0)
479		return err;
480	return 1;
481}
482EXPORT_SYMBOL_GPL(snd_hdac_regmap_update_raw);
483