1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21319b2f6SOder Chiou /*
31319b2f6SOder Chiou * rt5645.c -- RT5645 ALSA SoC audio codec driver
41319b2f6SOder Chiou *
51319b2f6SOder Chiou * Copyright 2013 Realtek Semiconductor Corp.
61319b2f6SOder Chiou * Author: Bard Liao <bardliao@realtek.com>
71319b2f6SOder Chiou */
81319b2f6SOder Chiou
91319b2f6SOder Chiou #include <linux/module.h>
101319b2f6SOder Chiou #include <linux/moduleparam.h>
111319b2f6SOder Chiou #include <linux/init.h>
121319b2f6SOder Chiou #include <linux/delay.h>
131319b2f6SOder Chiou #include <linux/pm.h>
141319b2f6SOder Chiou #include <linux/i2c.h>
151319b2f6SOder Chiou #include <linux/platform_device.h>
161319b2f6SOder Chiou #include <linux/spi/spi.h>
17baf2a0e1SFang, Yang A #include <linux/gpio/consumer.h>
183168c201SFang, Yang A #include <linux/acpi.h>
1978c34fd4SFang, Yang A #include <linux/dmi.h>
209fc114c5SKoro Chen #include <linux/regulator/consumer.h>
211319b2f6SOder Chiou #include <sound/core.h>
221319b2f6SOder Chiou #include <sound/pcm.h>
231319b2f6SOder Chiou #include <sound/pcm_params.h>
241319b2f6SOder Chiou #include <sound/jack.h>
251319b2f6SOder Chiou #include <sound/soc.h>
261319b2f6SOder Chiou #include <sound/soc-dapm.h>
271319b2f6SOder Chiou #include <sound/initval.h>
281319b2f6SOder Chiou #include <sound/tlv.h>
291319b2f6SOder Chiou
3049ef7925SOder Chiou #include "rl6231.h"
311319b2f6SOder Chiou #include "rt5645.h"
321319b2f6SOder Chiou
334999b021STakashi Iwai #define QUIRK_INV_JD1_1(q) ((q) & 1)
344999b021STakashi Iwai #define QUIRK_LEVEL_IRQ(q) (((q) >> 1) & 1)
354999b021STakashi Iwai #define QUIRK_IN2_DIFF(q) (((q) >> 2) & 1)
3628c98849SChris Chiu #define QUIRK_INV_HP_POL(q) (((q) >> 3) & 1)
374999b021STakashi Iwai #define QUIRK_JD_MODE(q) (((q) >> 4) & 7)
384999b021STakashi Iwai #define QUIRK_DMIC1_DATA_PIN(q) (((q) >> 8) & 3)
394999b021STakashi Iwai #define QUIRK_DMIC2_DATA_PIN(q) (((q) >> 12) & 3)
404999b021STakashi Iwai
414999b021STakashi Iwai static unsigned int quirk = -1;
424999b021STakashi Iwai module_param(quirk, uint, 0444);
434999b021STakashi Iwai MODULE_PARM_DESC(quirk, "RT5645 pdata quirk override");
444999b021STakashi Iwai
4521f60348SChris Chiu static const struct acpi_gpio_mapping *cht_rt5645_gpios;
4621f60348SChris Chiu
471319b2f6SOder Chiou #define RT5645_DEVICE_ID 0x6308
485c4ca99dSBard Liao #define RT5650_DEVICE_ID 0x6419
491319b2f6SOder Chiou
501319b2f6SOder Chiou #define RT5645_PR_RANGE_BASE (0xff + 1)
511319b2f6SOder Chiou #define RT5645_PR_SPACING 0x100
521319b2f6SOder Chiou
531319b2f6SOder Chiou #define RT5645_PR_BASE (RT5645_PR_RANGE_BASE + (0 * RT5645_PR_SPACING))
541319b2f6SOder Chiou
55be77b38aSOder Chiou #define RT5645_HWEQ_NUM 57
56be77b38aSOder Chiou
570c279a59SAkshu Agrawal #define TIME_TO_POWER_MS 400
580c279a59SAkshu Agrawal
591319b2f6SOder Chiou static const struct regmap_range_cfg rt5645_ranges[] = {
601319b2f6SOder Chiou {
611319b2f6SOder Chiou .name = "PR",
621319b2f6SOder Chiou .range_min = RT5645_PR_BASE,
631319b2f6SOder Chiou .range_max = RT5645_PR_BASE + 0xf8,
641319b2f6SOder Chiou .selector_reg = RT5645_PRIV_INDEX,
651319b2f6SOder Chiou .selector_mask = 0xff,
661319b2f6SOder Chiou .selector_shift = 0x0,
671319b2f6SOder Chiou .window_start = RT5645_PRIV_DATA,
681319b2f6SOder Chiou .window_len = 0x1,
691319b2f6SOder Chiou },
701319b2f6SOder Chiou };
711319b2f6SOder Chiou
728019ff6cSNariman Poushin static const struct reg_sequence init_list[] = {
731319b2f6SOder Chiou {RT5645_PR_BASE + 0x3d, 0x3600},
74105e56f1SBard Liao {RT5645_PR_BASE + 0x1c, 0xfd70},
754809b96eSOder Chiou {RT5645_PR_BASE + 0x20, 0x611f},
764809b96eSOder Chiou {RT5645_PR_BASE + 0x21, 0x4040},
774809b96eSOder Chiou {RT5645_PR_BASE + 0x23, 0x0004},
78e62ebf15SBard Liao {RT5645_ASRC_4, 0x0120},
791319b2f6SOder Chiou };
801319b2f6SOder Chiou
818019ff6cSNariman Poushin static const struct reg_sequence rt5650_init_list[] = {
825c4ca99dSBard Liao {0xf6, 0x0100},
83aa98697cSShuming Fan {RT5645_PWR_ANLG1, 0x02},
845c4ca99dSBard Liao };
855c4ca99dSBard Liao
861319b2f6SOder Chiou static const struct reg_default rt5645_reg[] = {
871319b2f6SOder Chiou { 0x00, 0x0000 },
881319b2f6SOder Chiou { 0x01, 0xc8c8 },
891319b2f6SOder Chiou { 0x02, 0xc8c8 },
901319b2f6SOder Chiou { 0x03, 0xc8c8 },
911319b2f6SOder Chiou { 0x0a, 0x0002 },
921319b2f6SOder Chiou { 0x0b, 0x2827 },
931319b2f6SOder Chiou { 0x0c, 0xe000 },
941319b2f6SOder Chiou { 0x0d, 0x0000 },
951319b2f6SOder Chiou { 0x0e, 0x0000 },
961319b2f6SOder Chiou { 0x0f, 0x0808 },
971319b2f6SOder Chiou { 0x14, 0x3333 },
981319b2f6SOder Chiou { 0x16, 0x4b00 },
991319b2f6SOder Chiou { 0x18, 0x018b },
1001319b2f6SOder Chiou { 0x19, 0xafaf },
1011319b2f6SOder Chiou { 0x1a, 0xafaf },
1021319b2f6SOder Chiou { 0x1b, 0x0001 },
1031319b2f6SOder Chiou { 0x1c, 0x2f2f },
1041319b2f6SOder Chiou { 0x1d, 0x2f2f },
1051319b2f6SOder Chiou { 0x1e, 0x0000 },
1061319b2f6SOder Chiou { 0x20, 0x0000 },
1071319b2f6SOder Chiou { 0x27, 0x7060 },
1081319b2f6SOder Chiou { 0x28, 0x7070 },
1091319b2f6SOder Chiou { 0x29, 0x8080 },
1101319b2f6SOder Chiou { 0x2a, 0x5656 },
1111319b2f6SOder Chiou { 0x2b, 0x5454 },
1121319b2f6SOder Chiou { 0x2c, 0xaaa0 },
1135c4ca99dSBard Liao { 0x2d, 0x0000 },
1141319b2f6SOder Chiou { 0x2f, 0x1002 },
1151319b2f6SOder Chiou { 0x31, 0x5000 },
1161319b2f6SOder Chiou { 0x32, 0x0000 },
1171319b2f6SOder Chiou { 0x33, 0x0000 },
1181319b2f6SOder Chiou { 0x34, 0x0000 },
1191319b2f6SOder Chiou { 0x35, 0x0000 },
1201319b2f6SOder Chiou { 0x3b, 0x0000 },
1211319b2f6SOder Chiou { 0x3c, 0x007f },
1221319b2f6SOder Chiou { 0x3d, 0x0000 },
1231319b2f6SOder Chiou { 0x3e, 0x007f },
1241319b2f6SOder Chiou { 0x3f, 0x0000 },
1251319b2f6SOder Chiou { 0x40, 0x001f },
1261319b2f6SOder Chiou { 0x41, 0x0000 },
1271319b2f6SOder Chiou { 0x42, 0x001f },
1281319b2f6SOder Chiou { 0x45, 0x6000 },
1291319b2f6SOder Chiou { 0x46, 0x003e },
1301319b2f6SOder Chiou { 0x47, 0x003e },
1311319b2f6SOder Chiou { 0x48, 0xf807 },
1321319b2f6SOder Chiou { 0x4a, 0x0004 },
1331319b2f6SOder Chiou { 0x4d, 0x0000 },
1341319b2f6SOder Chiou { 0x4e, 0x0000 },
1351319b2f6SOder Chiou { 0x4f, 0x01ff },
1361319b2f6SOder Chiou { 0x50, 0x0000 },
1371319b2f6SOder Chiou { 0x51, 0x0000 },
1381319b2f6SOder Chiou { 0x52, 0x01ff },
1391319b2f6SOder Chiou { 0x53, 0xf000 },
1401319b2f6SOder Chiou { 0x56, 0x0111 },
1411319b2f6SOder Chiou { 0x57, 0x0064 },
1421319b2f6SOder Chiou { 0x58, 0xef0e },
1431319b2f6SOder Chiou { 0x59, 0xf0f0 },
1441319b2f6SOder Chiou { 0x5a, 0xef0e },
1451319b2f6SOder Chiou { 0x5b, 0xf0f0 },
1461319b2f6SOder Chiou { 0x5c, 0xef0e },
1471319b2f6SOder Chiou { 0x5d, 0xf0f0 },
1481319b2f6SOder Chiou { 0x5e, 0xf000 },
1491319b2f6SOder Chiou { 0x5f, 0x0000 },
1501319b2f6SOder Chiou { 0x61, 0x0300 },
1511319b2f6SOder Chiou { 0x62, 0x0000 },
1521319b2f6SOder Chiou { 0x63, 0x00c2 },
1531319b2f6SOder Chiou { 0x64, 0x0000 },
1541319b2f6SOder Chiou { 0x65, 0x0000 },
1551319b2f6SOder Chiou { 0x66, 0x0000 },
1561319b2f6SOder Chiou { 0x6a, 0x0000 },
1571319b2f6SOder Chiou { 0x6c, 0x0aaa },
1581319b2f6SOder Chiou { 0x70, 0x8000 },
1591319b2f6SOder Chiou { 0x71, 0x8000 },
1601319b2f6SOder Chiou { 0x72, 0x8000 },
1611319b2f6SOder Chiou { 0x73, 0x7770 },
1621319b2f6SOder Chiou { 0x74, 0x3e00 },
1631319b2f6SOder Chiou { 0x75, 0x2409 },
1641319b2f6SOder Chiou { 0x76, 0x000a },
1651319b2f6SOder Chiou { 0x77, 0x0c00 },
1661319b2f6SOder Chiou { 0x78, 0x0000 },
167df078d29SFang, Yang A { 0x79, 0x0123 },
1681319b2f6SOder Chiou { 0x80, 0x0000 },
1691319b2f6SOder Chiou { 0x81, 0x0000 },
1701319b2f6SOder Chiou { 0x82, 0x0000 },
1711319b2f6SOder Chiou { 0x83, 0x0000 },
1721319b2f6SOder Chiou { 0x84, 0x0000 },
1731319b2f6SOder Chiou { 0x85, 0x0000 },
174e62ebf15SBard Liao { 0x8a, 0x0120 },
1751319b2f6SOder Chiou { 0x8e, 0x0004 },
1761319b2f6SOder Chiou { 0x8f, 0x1100 },
1771319b2f6SOder Chiou { 0x90, 0x0646 },
1781319b2f6SOder Chiou { 0x91, 0x0c06 },
1791319b2f6SOder Chiou { 0x93, 0x0000 },
1801319b2f6SOder Chiou { 0x94, 0x0200 },
1811319b2f6SOder Chiou { 0x95, 0x0000 },
1821319b2f6SOder Chiou { 0x9a, 0x2184 },
1831319b2f6SOder Chiou { 0x9b, 0x010a },
1841319b2f6SOder Chiou { 0x9c, 0x0aea },
1851319b2f6SOder Chiou { 0x9d, 0x000c },
1861319b2f6SOder Chiou { 0x9e, 0x0400 },
1871319b2f6SOder Chiou { 0xa0, 0xa0a8 },
1881319b2f6SOder Chiou { 0xa1, 0x0059 },
1891319b2f6SOder Chiou { 0xa2, 0x0001 },
1901319b2f6SOder Chiou { 0xae, 0x6000 },
1911319b2f6SOder Chiou { 0xaf, 0x0000 },
1921319b2f6SOder Chiou { 0xb0, 0x6000 },
1931319b2f6SOder Chiou { 0xb1, 0x0000 },
1941319b2f6SOder Chiou { 0xb2, 0x0000 },
1951319b2f6SOder Chiou { 0xb3, 0x001f },
1961319b2f6SOder Chiou { 0xb4, 0x020c },
1971319b2f6SOder Chiou { 0xb5, 0x1f00 },
1981319b2f6SOder Chiou { 0xb6, 0x0000 },
1991319b2f6SOder Chiou { 0xbb, 0x0000 },
2001319b2f6SOder Chiou { 0xbc, 0x0000 },
2011319b2f6SOder Chiou { 0xbd, 0x0000 },
2021319b2f6SOder Chiou { 0xbe, 0x0000 },
2031319b2f6SOder Chiou { 0xbf, 0x3100 },
2041319b2f6SOder Chiou { 0xc0, 0x0000 },
2051319b2f6SOder Chiou { 0xc1, 0x0000 },
2061319b2f6SOder Chiou { 0xc2, 0x0000 },
2071319b2f6SOder Chiou { 0xc3, 0x2000 },
2081319b2f6SOder Chiou { 0xcd, 0x0000 },
2091319b2f6SOder Chiou { 0xce, 0x0000 },
2101319b2f6SOder Chiou { 0xcf, 0x1813 },
2111319b2f6SOder Chiou { 0xd0, 0x0690 },
2121319b2f6SOder Chiou { 0xd1, 0x1c17 },
2131319b2f6SOder Chiou { 0xd3, 0xb320 },
2141319b2f6SOder Chiou { 0xd4, 0x0000 },
2151319b2f6SOder Chiou { 0xd6, 0x0400 },
2161319b2f6SOder Chiou { 0xd9, 0x0809 },
2171319b2f6SOder Chiou { 0xda, 0x0000 },
2181319b2f6SOder Chiou { 0xdb, 0x0003 },
2191319b2f6SOder Chiou { 0xdc, 0x0049 },
2201319b2f6SOder Chiou { 0xdd, 0x001b },
2215c4ca99dSBard Liao { 0xdf, 0x0008 },
2225c4ca99dSBard Liao { 0xe0, 0x4000 },
2231319b2f6SOder Chiou { 0xe6, 0x8000 },
2241319b2f6SOder Chiou { 0xe7, 0x0200 },
2251319b2f6SOder Chiou { 0xec, 0xb300 },
2261319b2f6SOder Chiou { 0xed, 0x0000 },
2271319b2f6SOder Chiou { 0xf0, 0x001f },
2281319b2f6SOder Chiou { 0xf1, 0x020c },
2291319b2f6SOder Chiou { 0xf2, 0x1f00 },
2301319b2f6SOder Chiou { 0xf3, 0x0000 },
2311319b2f6SOder Chiou { 0xf4, 0x4000 },
2321319b2f6SOder Chiou { 0xf8, 0x0000 },
2331319b2f6SOder Chiou { 0xf9, 0x0000 },
2341319b2f6SOder Chiou { 0xfa, 0x2060 },
2351319b2f6SOder Chiou { 0xfb, 0x4040 },
2361319b2f6SOder Chiou { 0xfc, 0x0000 },
2371319b2f6SOder Chiou { 0xfd, 0x0002 },
2381319b2f6SOder Chiou { 0xfe, 0x10ec },
2391319b2f6SOder Chiou { 0xff, 0x6308 },
2401319b2f6SOder Chiou };
2411319b2f6SOder Chiou
24249abc6cdSBard Liao static const struct reg_default rt5650_reg[] = {
24349abc6cdSBard Liao { 0x00, 0x0000 },
24449abc6cdSBard Liao { 0x01, 0xc8c8 },
24549abc6cdSBard Liao { 0x02, 0xc8c8 },
24649abc6cdSBard Liao { 0x03, 0xc8c8 },
24749abc6cdSBard Liao { 0x0a, 0x0002 },
24849abc6cdSBard Liao { 0x0b, 0x2827 },
24949abc6cdSBard Liao { 0x0c, 0xe000 },
25049abc6cdSBard Liao { 0x0d, 0x0000 },
25149abc6cdSBard Liao { 0x0e, 0x0000 },
25249abc6cdSBard Liao { 0x0f, 0x0808 },
25349abc6cdSBard Liao { 0x14, 0x3333 },
25449abc6cdSBard Liao { 0x16, 0x4b00 },
25549abc6cdSBard Liao { 0x18, 0x018b },
25649abc6cdSBard Liao { 0x19, 0xafaf },
25749abc6cdSBard Liao { 0x1a, 0xafaf },
25849abc6cdSBard Liao { 0x1b, 0x0001 },
25949abc6cdSBard Liao { 0x1c, 0x2f2f },
26049abc6cdSBard Liao { 0x1d, 0x2f2f },
26149abc6cdSBard Liao { 0x1e, 0x0000 },
26249abc6cdSBard Liao { 0x20, 0x0000 },
26349abc6cdSBard Liao { 0x27, 0x7060 },
26449abc6cdSBard Liao { 0x28, 0x7070 },
26549abc6cdSBard Liao { 0x29, 0x8080 },
26649abc6cdSBard Liao { 0x2a, 0x5656 },
26749abc6cdSBard Liao { 0x2b, 0x5454 },
26849abc6cdSBard Liao { 0x2c, 0xaaa0 },
26949abc6cdSBard Liao { 0x2d, 0x0000 },
270fdfe3b32SBard Liao { 0x2f, 0x5002 },
27149abc6cdSBard Liao { 0x31, 0x5000 },
27249abc6cdSBard Liao { 0x32, 0x0000 },
27349abc6cdSBard Liao { 0x33, 0x0000 },
27449abc6cdSBard Liao { 0x34, 0x0000 },
27549abc6cdSBard Liao { 0x35, 0x0000 },
27649abc6cdSBard Liao { 0x3b, 0x0000 },
27749abc6cdSBard Liao { 0x3c, 0x007f },
27849abc6cdSBard Liao { 0x3d, 0x0000 },
27949abc6cdSBard Liao { 0x3e, 0x007f },
28049abc6cdSBard Liao { 0x3f, 0x0000 },
28149abc6cdSBard Liao { 0x40, 0x001f },
28249abc6cdSBard Liao { 0x41, 0x0000 },
28349abc6cdSBard Liao { 0x42, 0x001f },
28449abc6cdSBard Liao { 0x45, 0x6000 },
28549abc6cdSBard Liao { 0x46, 0x003e },
28649abc6cdSBard Liao { 0x47, 0x003e },
28749abc6cdSBard Liao { 0x48, 0xf807 },
28849abc6cdSBard Liao { 0x4a, 0x0004 },
28949abc6cdSBard Liao { 0x4d, 0x0000 },
29049abc6cdSBard Liao { 0x4e, 0x0000 },
29149abc6cdSBard Liao { 0x4f, 0x01ff },
29249abc6cdSBard Liao { 0x50, 0x0000 },
29349abc6cdSBard Liao { 0x51, 0x0000 },
29449abc6cdSBard Liao { 0x52, 0x01ff },
29549abc6cdSBard Liao { 0x53, 0xf000 },
29649abc6cdSBard Liao { 0x56, 0x0111 },
29749abc6cdSBard Liao { 0x57, 0x0064 },
29849abc6cdSBard Liao { 0x58, 0xef0e },
29949abc6cdSBard Liao { 0x59, 0xf0f0 },
30049abc6cdSBard Liao { 0x5a, 0xef0e },
30149abc6cdSBard Liao { 0x5b, 0xf0f0 },
30249abc6cdSBard Liao { 0x5c, 0xef0e },
30349abc6cdSBard Liao { 0x5d, 0xf0f0 },
30449abc6cdSBard Liao { 0x5e, 0xf000 },
30549abc6cdSBard Liao { 0x5f, 0x0000 },
30649abc6cdSBard Liao { 0x61, 0x0300 },
30749abc6cdSBard Liao { 0x62, 0x0000 },
30849abc6cdSBard Liao { 0x63, 0x00c2 },
30949abc6cdSBard Liao { 0x64, 0x0000 },
31049abc6cdSBard Liao { 0x65, 0x0000 },
31149abc6cdSBard Liao { 0x66, 0x0000 },
31249abc6cdSBard Liao { 0x6a, 0x0000 },
31349abc6cdSBard Liao { 0x6c, 0x0aaa },
31449abc6cdSBard Liao { 0x70, 0x8000 },
31549abc6cdSBard Liao { 0x71, 0x8000 },
31649abc6cdSBard Liao { 0x72, 0x8000 },
31749abc6cdSBard Liao { 0x73, 0x7770 },
31849abc6cdSBard Liao { 0x74, 0x3e00 },
31949abc6cdSBard Liao { 0x75, 0x2409 },
32049abc6cdSBard Liao { 0x76, 0x000a },
32149abc6cdSBard Liao { 0x77, 0x0c00 },
32249abc6cdSBard Liao { 0x78, 0x0000 },
32349abc6cdSBard Liao { 0x79, 0x0123 },
32449abc6cdSBard Liao { 0x7a, 0x0123 },
32549abc6cdSBard Liao { 0x80, 0x0000 },
32649abc6cdSBard Liao { 0x81, 0x0000 },
32749abc6cdSBard Liao { 0x82, 0x0000 },
32849abc6cdSBard Liao { 0x83, 0x0000 },
32949abc6cdSBard Liao { 0x84, 0x0000 },
33049abc6cdSBard Liao { 0x85, 0x0000 },
331e62ebf15SBard Liao { 0x8a, 0x0120 },
33249abc6cdSBard Liao { 0x8e, 0x0004 },
33349abc6cdSBard Liao { 0x8f, 0x1100 },
33449abc6cdSBard Liao { 0x90, 0x0646 },
33549abc6cdSBard Liao { 0x91, 0x0c06 },
33649abc6cdSBard Liao { 0x93, 0x0000 },
33749abc6cdSBard Liao { 0x94, 0x0200 },
33849abc6cdSBard Liao { 0x95, 0x0000 },
33949abc6cdSBard Liao { 0x9a, 0x2184 },
34049abc6cdSBard Liao { 0x9b, 0x010a },
34149abc6cdSBard Liao { 0x9c, 0x0aea },
34249abc6cdSBard Liao { 0x9d, 0x000c },
34349abc6cdSBard Liao { 0x9e, 0x0400 },
34449abc6cdSBard Liao { 0xa0, 0xa0a8 },
34549abc6cdSBard Liao { 0xa1, 0x0059 },
34649abc6cdSBard Liao { 0xa2, 0x0001 },
34749abc6cdSBard Liao { 0xae, 0x6000 },
34849abc6cdSBard Liao { 0xaf, 0x0000 },
34949abc6cdSBard Liao { 0xb0, 0x6000 },
35049abc6cdSBard Liao { 0xb1, 0x0000 },
35149abc6cdSBard Liao { 0xb2, 0x0000 },
35249abc6cdSBard Liao { 0xb3, 0x001f },
35349abc6cdSBard Liao { 0xb4, 0x020c },
35449abc6cdSBard Liao { 0xb5, 0x1f00 },
35549abc6cdSBard Liao { 0xb6, 0x0000 },
35649abc6cdSBard Liao { 0xbb, 0x0000 },
35749abc6cdSBard Liao { 0xbc, 0x0000 },
35849abc6cdSBard Liao { 0xbd, 0x0000 },
35949abc6cdSBard Liao { 0xbe, 0x0000 },
36049abc6cdSBard Liao { 0xbf, 0x3100 },
36149abc6cdSBard Liao { 0xc0, 0x0000 },
36249abc6cdSBard Liao { 0xc1, 0x0000 },
36349abc6cdSBard Liao { 0xc2, 0x0000 },
36449abc6cdSBard Liao { 0xc3, 0x2000 },
36549abc6cdSBard Liao { 0xcd, 0x0000 },
36649abc6cdSBard Liao { 0xce, 0x0000 },
36749abc6cdSBard Liao { 0xcf, 0x1813 },
36849abc6cdSBard Liao { 0xd0, 0x0690 },
36949abc6cdSBard Liao { 0xd1, 0x1c17 },
37049abc6cdSBard Liao { 0xd3, 0xb320 },
37149abc6cdSBard Liao { 0xd4, 0x0000 },
37249abc6cdSBard Liao { 0xd6, 0x0400 },
37349abc6cdSBard Liao { 0xd9, 0x0809 },
37449abc6cdSBard Liao { 0xda, 0x0000 },
37549abc6cdSBard Liao { 0xdb, 0x0003 },
37649abc6cdSBard Liao { 0xdc, 0x0049 },
37749abc6cdSBard Liao { 0xdd, 0x001b },
37849abc6cdSBard Liao { 0xdf, 0x0008 },
37949abc6cdSBard Liao { 0xe0, 0x4000 },
38049abc6cdSBard Liao { 0xe6, 0x8000 },
38149abc6cdSBard Liao { 0xe7, 0x0200 },
38249abc6cdSBard Liao { 0xec, 0xb300 },
38349abc6cdSBard Liao { 0xed, 0x0000 },
38449abc6cdSBard Liao { 0xf0, 0x001f },
38549abc6cdSBard Liao { 0xf1, 0x020c },
38649abc6cdSBard Liao { 0xf2, 0x1f00 },
38749abc6cdSBard Liao { 0xf3, 0x0000 },
38849abc6cdSBard Liao { 0xf4, 0x4000 },
38949abc6cdSBard Liao { 0xf8, 0x0000 },
39049abc6cdSBard Liao { 0xf9, 0x0000 },
39149abc6cdSBard Liao { 0xfa, 0x2060 },
39249abc6cdSBard Liao { 0xfb, 0x4040 },
39349abc6cdSBard Liao { 0xfc, 0x0000 },
39449abc6cdSBard Liao { 0xfd, 0x0002 },
39549abc6cdSBard Liao { 0xfe, 0x10ec },
39649abc6cdSBard Liao { 0xff, 0x6308 },
39749abc6cdSBard Liao };
39849abc6cdSBard Liao
399be77b38aSOder Chiou struct rt5645_eq_param_s {
400be77b38aSOder Chiou unsigned short reg;
401be77b38aSOder Chiou unsigned short val;
402be77b38aSOder Chiou };
403be77b38aSOder Chiou
40460b52ed6SBard liao struct rt5645_eq_param_s_be16 {
40560b52ed6SBard liao __be16 reg;
40660b52ed6SBard liao __be16 val;
40760b52ed6SBard liao };
40860b52ed6SBard liao
4099fc114c5SKoro Chen static const char *const rt5645_supply_names[] = {
4109fc114c5SKoro Chen "avdd",
4119fc114c5SKoro Chen "cpvdd",
4129fc114c5SKoro Chen };
4139fc114c5SKoro Chen
414452801caSHans de Goede struct rt5645_platform_data {
415452801caSHans de Goede /* IN2 can optionally be differential */
416452801caSHans de Goede bool in2_diff;
417452801caSHans de Goede
418452801caSHans de Goede unsigned int dmic1_data_pin;
419452801caSHans de Goede /* 0 = IN2N; 1 = GPIO5; 2 = GPIO11 */
420452801caSHans de Goede unsigned int dmic2_data_pin;
421452801caSHans de Goede /* 0 = IN2P; 1 = GPIO6; 2 = GPIO10; 3 = GPIO12 */
422452801caSHans de Goede
423452801caSHans de Goede unsigned int jd_mode;
424452801caSHans de Goede /* Use level triggered irq */
425452801caSHans de Goede bool level_trigger_irq;
426452801caSHans de Goede /* Invert JD1_1 status polarity */
427452801caSHans de Goede bool inv_jd1_1;
428452801caSHans de Goede /* Invert HP detect status polarity */
429452801caSHans de Goede bool inv_hp_pol;
430452801caSHans de Goede
431452801caSHans de Goede /* Value to assign to snd_soc_card.long_name */
432452801caSHans de Goede const char *long_name;
4333f004d2dSHans de Goede
4343f004d2dSHans de Goede /* Some (package) variants have the headset-mic pin not-connected */
4353f004d2dSHans de Goede bool no_headset_mic;
436452801caSHans de Goede };
437452801caSHans de Goede
4389fc114c5SKoro Chen struct rt5645_priv {
43979223bf1SKuninori Morimoto struct snd_soc_component *component;
4409fc114c5SKoro Chen struct rt5645_platform_data pdata;
4419fc114c5SKoro Chen struct regmap *regmap;
4429fc114c5SKoro Chen struct i2c_client *i2c;
4439fc114c5SKoro Chen struct gpio_desc *gpiod_hp_det;
444*7904b066SDerek Fang struct gpio_desc *gpiod_cbj_sleeve;
4459fc114c5SKoro Chen struct snd_soc_jack *hp_jack;
4469fc114c5SKoro Chen struct snd_soc_jack *mic_jack;
4479fc114c5SKoro Chen struct snd_soc_jack *btn_jack;
4487099ee85SOder Chiou struct delayed_work jack_detect_work, rcclock_work;
4499fc114c5SKoro Chen struct regulator_bulk_data supplies[ARRAY_SIZE(rt5645_supply_names)];
450be77b38aSOder Chiou struct rt5645_eq_param_s *eq_param;
4517ff6319eSBard Liao struct timer_list btn_check_timer;
4528f82f2e4SShuming Fan struct mutex jd_mutex;
4539fc114c5SKoro Chen
4549fc114c5SKoro Chen int codec_type;
4559fc114c5SKoro Chen int sysclk;
4569fc114c5SKoro Chen int sysclk_src;
4579fc114c5SKoro Chen int lrck[RT5645_AIFS];
4589fc114c5SKoro Chen int bclk[RT5645_AIFS];
4599fc114c5SKoro Chen int master[RT5645_AIFS];
4609fc114c5SKoro Chen
4619fc114c5SKoro Chen int pll_src;
4629fc114c5SKoro Chen int pll_in;
4639fc114c5SKoro Chen int pll_out;
4649fc114c5SKoro Chen
4659fc114c5SKoro Chen int jack_type;
4669fc114c5SKoro Chen bool en_button_func;
46750f510a3SBard Liao int v_id;
4689fc114c5SKoro Chen };
4699fc114c5SKoro Chen
rt5645_reset(struct snd_soc_component * component)47079223bf1SKuninori Morimoto static int rt5645_reset(struct snd_soc_component *component)
4711319b2f6SOder Chiou {
47279223bf1SKuninori Morimoto return snd_soc_component_write(component, RT5645_RESET, 0);
4731319b2f6SOder Chiou }
4741319b2f6SOder Chiou
rt5645_volatile_register(struct device * dev,unsigned int reg)4751319b2f6SOder Chiou static bool rt5645_volatile_register(struct device *dev, unsigned int reg)
4761319b2f6SOder Chiou {
4771319b2f6SOder Chiou int i;
4781319b2f6SOder Chiou
4791319b2f6SOder Chiou for (i = 0; i < ARRAY_SIZE(rt5645_ranges); i++) {
4801319b2f6SOder Chiou if (reg >= rt5645_ranges[i].range_min &&
4811319b2f6SOder Chiou reg <= rt5645_ranges[i].range_max) {
4821319b2f6SOder Chiou return true;
4831319b2f6SOder Chiou }
4841319b2f6SOder Chiou }
4851319b2f6SOder Chiou
4861319b2f6SOder Chiou switch (reg) {
4871319b2f6SOder Chiou case RT5645_RESET:
48881467efcSBard Liao case RT5645_PRIV_INDEX:
4891319b2f6SOder Chiou case RT5645_PRIV_DATA:
4901319b2f6SOder Chiou case RT5645_IN1_CTRL1:
4911319b2f6SOder Chiou case RT5645_IN1_CTRL2:
4921319b2f6SOder Chiou case RT5645_IN1_CTRL3:
4931319b2f6SOder Chiou case RT5645_A_JD_CTRL1:
4941319b2f6SOder Chiou case RT5645_ADC_EQ_CTRL1:
4951319b2f6SOder Chiou case RT5645_EQ_CTRL1:
4961319b2f6SOder Chiou case RT5645_ALC_CTRL_1:
4971319b2f6SOder Chiou case RT5645_IRQ_CTRL2:
4981319b2f6SOder Chiou case RT5645_IRQ_CTRL3:
4991319b2f6SOder Chiou case RT5645_INT_IRQ_ST:
5001319b2f6SOder Chiou case RT5645_IL_CMD:
5015c4ca99dSBard Liao case RT5650_4BTN_IL_CMD1:
5021319b2f6SOder Chiou case RT5645_VENDOR_ID:
5031319b2f6SOder Chiou case RT5645_VENDOR_ID1:
5041319b2f6SOder Chiou case RT5645_VENDOR_ID2:
50571bfa9b4SOder Chiou return true;
5061319b2f6SOder Chiou default:
50771bfa9b4SOder Chiou return false;
5081319b2f6SOder Chiou }
5091319b2f6SOder Chiou }
5101319b2f6SOder Chiou
rt5645_readable_register(struct device * dev,unsigned int reg)5111319b2f6SOder Chiou static bool rt5645_readable_register(struct device *dev, unsigned int reg)
5121319b2f6SOder Chiou {
5131319b2f6SOder Chiou int i;
5141319b2f6SOder Chiou
5151319b2f6SOder Chiou for (i = 0; i < ARRAY_SIZE(rt5645_ranges); i++) {
5161319b2f6SOder Chiou if (reg >= rt5645_ranges[i].range_min &&
5171319b2f6SOder Chiou reg <= rt5645_ranges[i].range_max) {
5181319b2f6SOder Chiou return true;
5191319b2f6SOder Chiou }
5201319b2f6SOder Chiou }
5211319b2f6SOder Chiou
5221319b2f6SOder Chiou switch (reg) {
5231319b2f6SOder Chiou case RT5645_RESET:
5241319b2f6SOder Chiou case RT5645_SPK_VOL:
5251319b2f6SOder Chiou case RT5645_HP_VOL:
5261319b2f6SOder Chiou case RT5645_LOUT1:
5271319b2f6SOder Chiou case RT5645_IN1_CTRL1:
5281319b2f6SOder Chiou case RT5645_IN1_CTRL2:
5291319b2f6SOder Chiou case RT5645_IN1_CTRL3:
5301319b2f6SOder Chiou case RT5645_IN2_CTRL:
5311319b2f6SOder Chiou case RT5645_INL1_INR1_VOL:
5321319b2f6SOder Chiou case RT5645_SPK_FUNC_LIM:
5331319b2f6SOder Chiou case RT5645_ADJ_HPF_CTRL:
5341319b2f6SOder Chiou case RT5645_DAC1_DIG_VOL:
5351319b2f6SOder Chiou case RT5645_DAC2_DIG_VOL:
5361319b2f6SOder Chiou case RT5645_DAC_CTRL:
5371319b2f6SOder Chiou case RT5645_STO1_ADC_DIG_VOL:
5381319b2f6SOder Chiou case RT5645_MONO_ADC_DIG_VOL:
5391319b2f6SOder Chiou case RT5645_ADC_BST_VOL1:
5401319b2f6SOder Chiou case RT5645_ADC_BST_VOL2:
5411319b2f6SOder Chiou case RT5645_STO1_ADC_MIXER:
5421319b2f6SOder Chiou case RT5645_MONO_ADC_MIXER:
5431319b2f6SOder Chiou case RT5645_AD_DA_MIXER:
5441319b2f6SOder Chiou case RT5645_STO_DAC_MIXER:
5451319b2f6SOder Chiou case RT5645_MONO_DAC_MIXER:
5461319b2f6SOder Chiou case RT5645_DIG_MIXER:
5475c4ca99dSBard Liao case RT5650_A_DAC_SOUR:
5481319b2f6SOder Chiou case RT5645_DIG_INF1_DATA:
5491319b2f6SOder Chiou case RT5645_PDM_OUT_CTRL:
5501319b2f6SOder Chiou case RT5645_REC_L1_MIXER:
5511319b2f6SOder Chiou case RT5645_REC_L2_MIXER:
5521319b2f6SOder Chiou case RT5645_REC_R1_MIXER:
5531319b2f6SOder Chiou case RT5645_REC_R2_MIXER:
5541319b2f6SOder Chiou case RT5645_HPMIXL_CTRL:
5551319b2f6SOder Chiou case RT5645_HPOMIXL_CTRL:
5561319b2f6SOder Chiou case RT5645_HPMIXR_CTRL:
5571319b2f6SOder Chiou case RT5645_HPOMIXR_CTRL:
5581319b2f6SOder Chiou case RT5645_HPO_MIXER:
5591319b2f6SOder Chiou case RT5645_SPK_L_MIXER:
5601319b2f6SOder Chiou case RT5645_SPK_R_MIXER:
5611319b2f6SOder Chiou case RT5645_SPO_MIXER:
5621319b2f6SOder Chiou case RT5645_SPO_CLSD_RATIO:
5631319b2f6SOder Chiou case RT5645_OUT_L1_MIXER:
5641319b2f6SOder Chiou case RT5645_OUT_R1_MIXER:
5651319b2f6SOder Chiou case RT5645_OUT_L_GAIN1:
5661319b2f6SOder Chiou case RT5645_OUT_L_GAIN2:
5671319b2f6SOder Chiou case RT5645_OUT_R_GAIN1:
5681319b2f6SOder Chiou case RT5645_OUT_R_GAIN2:
5691319b2f6SOder Chiou case RT5645_LOUT_MIXER:
5701319b2f6SOder Chiou case RT5645_HAPTIC_CTRL1:
5711319b2f6SOder Chiou case RT5645_HAPTIC_CTRL2:
5721319b2f6SOder Chiou case RT5645_HAPTIC_CTRL3:
5731319b2f6SOder Chiou case RT5645_HAPTIC_CTRL4:
5741319b2f6SOder Chiou case RT5645_HAPTIC_CTRL5:
5751319b2f6SOder Chiou case RT5645_HAPTIC_CTRL6:
5761319b2f6SOder Chiou case RT5645_HAPTIC_CTRL7:
5771319b2f6SOder Chiou case RT5645_HAPTIC_CTRL8:
5781319b2f6SOder Chiou case RT5645_HAPTIC_CTRL9:
5791319b2f6SOder Chiou case RT5645_HAPTIC_CTRL10:
5801319b2f6SOder Chiou case RT5645_PWR_DIG1:
5811319b2f6SOder Chiou case RT5645_PWR_DIG2:
5821319b2f6SOder Chiou case RT5645_PWR_ANLG1:
5831319b2f6SOder Chiou case RT5645_PWR_ANLG2:
5841319b2f6SOder Chiou case RT5645_PWR_MIXER:
5851319b2f6SOder Chiou case RT5645_PWR_VOL:
5861319b2f6SOder Chiou case RT5645_PRIV_INDEX:
5871319b2f6SOder Chiou case RT5645_PRIV_DATA:
5881319b2f6SOder Chiou case RT5645_I2S1_SDP:
5891319b2f6SOder Chiou case RT5645_I2S2_SDP:
5901319b2f6SOder Chiou case RT5645_ADDA_CLK1:
5911319b2f6SOder Chiou case RT5645_ADDA_CLK2:
5921319b2f6SOder Chiou case RT5645_DMIC_CTRL1:
5931319b2f6SOder Chiou case RT5645_DMIC_CTRL2:
5941319b2f6SOder Chiou case RT5645_TDM_CTRL_1:
5951319b2f6SOder Chiou case RT5645_TDM_CTRL_2:
596df078d29SFang, Yang A case RT5645_TDM_CTRL_3:
5971fcb76dbSOder Chiou case RT5650_TDM_CTRL_4:
5981319b2f6SOder Chiou case RT5645_GLB_CLK:
5991319b2f6SOder Chiou case RT5645_PLL_CTRL1:
6001319b2f6SOder Chiou case RT5645_PLL_CTRL2:
6011319b2f6SOder Chiou case RT5645_ASRC_1:
6021319b2f6SOder Chiou case RT5645_ASRC_2:
6031319b2f6SOder Chiou case RT5645_ASRC_3:
6041319b2f6SOder Chiou case RT5645_ASRC_4:
6051319b2f6SOder Chiou case RT5645_DEPOP_M1:
6061319b2f6SOder Chiou case RT5645_DEPOP_M2:
6071319b2f6SOder Chiou case RT5645_DEPOP_M3:
608b1d42598SOder Chiou case RT5645_CHARGE_PUMP:
6091319b2f6SOder Chiou case RT5645_MICBIAS:
6101319b2f6SOder Chiou case RT5645_A_JD_CTRL1:
6111319b2f6SOder Chiou case RT5645_VAD_CTRL4:
6121319b2f6SOder Chiou case RT5645_CLSD_OUT_CTRL:
6131319b2f6SOder Chiou case RT5645_ADC_EQ_CTRL1:
6141319b2f6SOder Chiou case RT5645_ADC_EQ_CTRL2:
6151319b2f6SOder Chiou case RT5645_EQ_CTRL1:
6161319b2f6SOder Chiou case RT5645_EQ_CTRL2:
6171319b2f6SOder Chiou case RT5645_ALC_CTRL_1:
6181319b2f6SOder Chiou case RT5645_ALC_CTRL_2:
6191319b2f6SOder Chiou case RT5645_ALC_CTRL_3:
6201319b2f6SOder Chiou case RT5645_ALC_CTRL_4:
6211319b2f6SOder Chiou case RT5645_ALC_CTRL_5:
6221319b2f6SOder Chiou case RT5645_JD_CTRL:
6231319b2f6SOder Chiou case RT5645_IRQ_CTRL1:
6241319b2f6SOder Chiou case RT5645_IRQ_CTRL2:
6251319b2f6SOder Chiou case RT5645_IRQ_CTRL3:
6261319b2f6SOder Chiou case RT5645_INT_IRQ_ST:
6271319b2f6SOder Chiou case RT5645_GPIO_CTRL1:
6281319b2f6SOder Chiou case RT5645_GPIO_CTRL2:
6291319b2f6SOder Chiou case RT5645_GPIO_CTRL3:
6301319b2f6SOder Chiou case RT5645_BASS_BACK:
6311319b2f6SOder Chiou case RT5645_MP3_PLUS1:
6321319b2f6SOder Chiou case RT5645_MP3_PLUS2:
6331319b2f6SOder Chiou case RT5645_ADJ_HPF1:
6341319b2f6SOder Chiou case RT5645_ADJ_HPF2:
6351319b2f6SOder Chiou case RT5645_HP_CALIB_AMP_DET:
6361319b2f6SOder Chiou case RT5645_SV_ZCD1:
6371319b2f6SOder Chiou case RT5645_SV_ZCD2:
6381319b2f6SOder Chiou case RT5645_IL_CMD:
6391319b2f6SOder Chiou case RT5645_IL_CMD2:
6401319b2f6SOder Chiou case RT5645_IL_CMD3:
6415c4ca99dSBard Liao case RT5650_4BTN_IL_CMD1:
6425c4ca99dSBard Liao case RT5650_4BTN_IL_CMD2:
6431319b2f6SOder Chiou case RT5645_DRC1_HL_CTRL1:
6441319b2f6SOder Chiou case RT5645_DRC2_HL_CTRL1:
6451319b2f6SOder Chiou case RT5645_ADC_MONO_HP_CTRL1:
6461319b2f6SOder Chiou case RT5645_ADC_MONO_HP_CTRL2:
6471319b2f6SOder Chiou case RT5645_DRC2_CTRL1:
6481319b2f6SOder Chiou case RT5645_DRC2_CTRL2:
6491319b2f6SOder Chiou case RT5645_DRC2_CTRL3:
6501319b2f6SOder Chiou case RT5645_DRC2_CTRL4:
6511319b2f6SOder Chiou case RT5645_DRC2_CTRL5:
6521319b2f6SOder Chiou case RT5645_JD_CTRL3:
6531319b2f6SOder Chiou case RT5645_JD_CTRL4:
6541319b2f6SOder Chiou case RT5645_GEN_CTRL1:
6551319b2f6SOder Chiou case RT5645_GEN_CTRL2:
6561319b2f6SOder Chiou case RT5645_GEN_CTRL3:
6571319b2f6SOder Chiou case RT5645_VENDOR_ID:
6581319b2f6SOder Chiou case RT5645_VENDOR_ID1:
6591319b2f6SOder Chiou case RT5645_VENDOR_ID2:
66071bfa9b4SOder Chiou return true;
6611319b2f6SOder Chiou default:
66271bfa9b4SOder Chiou return false;
6631319b2f6SOder Chiou }
6641319b2f6SOder Chiou }
6651319b2f6SOder Chiou
6661319b2f6SOder Chiou static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
667177e1e1fSBard Liao static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -6525, 75, 0);
6681319b2f6SOder Chiou static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
669177e1e1fSBard Liao static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0);
6701319b2f6SOder Chiou static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0);
6711319b2f6SOder Chiou
6721319b2f6SOder Chiou /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */
6736d698a83SLars-Peter Clausen static const DECLARE_TLV_DB_RANGE(bst_tlv,
6741319b2f6SOder Chiou 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
6751319b2f6SOder Chiou 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
6761319b2f6SOder Chiou 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
6771319b2f6SOder Chiou 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
6781319b2f6SOder Chiou 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
6791319b2f6SOder Chiou 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
6806d698a83SLars-Peter Clausen 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0)
6816d698a83SLars-Peter Clausen );
6821319b2f6SOder Chiou
683e29fd55dSOder Chiou /* {-6, -4.5, -3, -1.5, 0, 0.82, 1.58, 2.28} dB */
684e29fd55dSOder Chiou static const DECLARE_TLV_DB_RANGE(spk_clsd_tlv,
685e29fd55dSOder Chiou 0, 4, TLV_DB_SCALE_ITEM(-600, 150, 0),
686e29fd55dSOder Chiou 5, 5, TLV_DB_SCALE_ITEM(82, 0, 0),
687e29fd55dSOder Chiou 6, 6, TLV_DB_SCALE_ITEM(158, 0, 0),
688e29fd55dSOder Chiou 7, 7, TLV_DB_SCALE_ITEM(228, 0, 0)
689e29fd55dSOder Chiou );
690e29fd55dSOder Chiou
rt5645_hweq_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)691be77b38aSOder Chiou static int rt5645_hweq_info(struct snd_kcontrol *kcontrol,
692be77b38aSOder Chiou struct snd_ctl_elem_info *uinfo)
693be77b38aSOder Chiou {
694be77b38aSOder Chiou uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
695be77b38aSOder Chiou uinfo->count = RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s);
696be77b38aSOder Chiou
697be77b38aSOder Chiou return 0;
698be77b38aSOder Chiou }
699be77b38aSOder Chiou
rt5645_hweq_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)700be77b38aSOder Chiou static int rt5645_hweq_get(struct snd_kcontrol *kcontrol,
701be77b38aSOder Chiou struct snd_ctl_elem_value *ucontrol)
702be77b38aSOder Chiou {
703be77b38aSOder Chiou struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
704be77b38aSOder Chiou struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
70560b52ed6SBard liao struct rt5645_eq_param_s_be16 *eq_param =
70660b52ed6SBard liao (struct rt5645_eq_param_s_be16 *)ucontrol->value.bytes.data;
707be77b38aSOder Chiou int i;
708be77b38aSOder Chiou
709be77b38aSOder Chiou for (i = 0; i < RT5645_HWEQ_NUM; i++) {
710be77b38aSOder Chiou eq_param[i].reg = cpu_to_be16(rt5645->eq_param[i].reg);
711be77b38aSOder Chiou eq_param[i].val = cpu_to_be16(rt5645->eq_param[i].val);
712be77b38aSOder Chiou }
713be77b38aSOder Chiou
714be77b38aSOder Chiou return 0;
715be77b38aSOder Chiou }
716be77b38aSOder Chiou
rt5645_validate_hweq(unsigned short reg)717be77b38aSOder Chiou static bool rt5645_validate_hweq(unsigned short reg)
718be77b38aSOder Chiou {
7195864cf7fSPierre-Louis Bossart if ((reg >= 0x1a4 && reg <= 0x1cd) || (reg >= 0x1e5 && reg <= 0x1f8) ||
720be77b38aSOder Chiou (reg == RT5645_EQ_CTRL2))
721be77b38aSOder Chiou return true;
722be77b38aSOder Chiou
723be77b38aSOder Chiou return false;
724be77b38aSOder Chiou }
725be77b38aSOder Chiou
rt5645_hweq_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)726be77b38aSOder Chiou static int rt5645_hweq_put(struct snd_kcontrol *kcontrol,
727be77b38aSOder Chiou struct snd_ctl_elem_value *ucontrol)
728be77b38aSOder Chiou {
729be77b38aSOder Chiou struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
730be77b38aSOder Chiou struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
73160b52ed6SBard liao struct rt5645_eq_param_s_be16 *eq_param =
73260b52ed6SBard liao (struct rt5645_eq_param_s_be16 *)ucontrol->value.bytes.data;
733be77b38aSOder Chiou int i;
734be77b38aSOder Chiou
735be77b38aSOder Chiou for (i = 0; i < RT5645_HWEQ_NUM; i++) {
73660b52ed6SBard liao rt5645->eq_param[i].reg = be16_to_cpu(eq_param[i].reg);
73760b52ed6SBard liao rt5645->eq_param[i].val = be16_to_cpu(eq_param[i].val);
738be77b38aSOder Chiou }
739be77b38aSOder Chiou
740be77b38aSOder Chiou /* The final setting of the table should be RT5645_EQ_CTRL2 */
741be77b38aSOder Chiou for (i = RT5645_HWEQ_NUM - 1; i >= 0; i--) {
74260b52ed6SBard liao if (rt5645->eq_param[i].reg == 0)
743be77b38aSOder Chiou continue;
74460b52ed6SBard liao else if (rt5645->eq_param[i].reg != RT5645_EQ_CTRL2)
745be77b38aSOder Chiou return 0;
746be77b38aSOder Chiou else
747be77b38aSOder Chiou break;
748be77b38aSOder Chiou }
749be77b38aSOder Chiou
750be77b38aSOder Chiou for (i = 0; i < RT5645_HWEQ_NUM; i++) {
75160b52ed6SBard liao if (!rt5645_validate_hweq(rt5645->eq_param[i].reg) &&
75260b52ed6SBard liao rt5645->eq_param[i].reg != 0)
753be77b38aSOder Chiou return 0;
75460b52ed6SBard liao else if (rt5645->eq_param[i].reg == 0)
755be77b38aSOder Chiou break;
756be77b38aSOder Chiou }
757be77b38aSOder Chiou
758be77b38aSOder Chiou return 0;
759be77b38aSOder Chiou }
760be77b38aSOder Chiou
761be77b38aSOder Chiou #define RT5645_HWEQ(xname) \
762be77b38aSOder Chiou { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
763be77b38aSOder Chiou .info = rt5645_hweq_info, \
764be77b38aSOder Chiou .get = rt5645_hweq_get, \
765be77b38aSOder Chiou .put = rt5645_hweq_put \
766be77b38aSOder Chiou }
767be77b38aSOder Chiou
rt5645_spk_put_volsw(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)7687099ee85SOder Chiou static int rt5645_spk_put_volsw(struct snd_kcontrol *kcontrol,
7697099ee85SOder Chiou struct snd_ctl_elem_value *ucontrol)
7707099ee85SOder Chiou {
7717099ee85SOder Chiou struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
7727099ee85SOder Chiou struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
7737099ee85SOder Chiou int ret;
7747099ee85SOder Chiou
7757099ee85SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_MICBIAS,
7767099ee85SOder Chiou RT5645_PWR_CLK25M_MASK, RT5645_PWR_CLK25M_PU);
7777099ee85SOder Chiou
7787099ee85SOder Chiou ret = snd_soc_put_volsw(kcontrol, ucontrol);
7797099ee85SOder Chiou
7806e5b143cSOder Chiou mod_delayed_work(system_power_efficient_wq, &rt5645->rcclock_work,
7817099ee85SOder Chiou msecs_to_jiffies(200));
7827099ee85SOder Chiou
7837099ee85SOder Chiou return ret;
7847099ee85SOder Chiou }
7857099ee85SOder Chiou
786467b1479SBard Liao static const char * const rt5645_dac1_vol_ctrl_mode_text[] = {
787467b1479SBard Liao "immediately", "zero crossing", "soft ramp"
788467b1479SBard Liao };
789467b1479SBard Liao
790467b1479SBard Liao static SOC_ENUM_SINGLE_DECL(
791467b1479SBard Liao rt5645_dac1_vol_ctrl_mode, RT5645_PR_BASE,
792467b1479SBard Liao RT5645_DA1_ZDET_SFT, rt5645_dac1_vol_ctrl_mode_text);
793467b1479SBard Liao
7941319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_snd_controls[] = {
7951319b2f6SOder Chiou /* Speaker Output Volume */
7961319b2f6SOder Chiou SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL,
7971319b2f6SOder Chiou RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1),
7987099ee85SOder Chiou SOC_DOUBLE_EXT_TLV("Speaker Playback Volume", RT5645_SPK_VOL,
7997099ee85SOder Chiou RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, snd_soc_get_volsw,
8007099ee85SOder Chiou rt5645_spk_put_volsw, out_vol_tlv),
8011319b2f6SOder Chiou
802e29fd55dSOder Chiou /* ClassD modulator Speaker Gain Ratio */
803e29fd55dSOder Chiou SOC_SINGLE_TLV("Speaker ClassD Playback Volume", RT5645_SPO_CLSD_RATIO,
804e29fd55dSOder Chiou RT5645_SPK_G_CLSD_SFT, 7, 0, spk_clsd_tlv),
805e29fd55dSOder Chiou
8061319b2f6SOder Chiou /* Headphone Output Volume */
807692768c4SNicolas Boichat SOC_DOUBLE("Headphone Channel Switch", RT5645_HP_VOL,
8081319b2f6SOder Chiou RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1),
809692768c4SNicolas Boichat SOC_DOUBLE_TLV("Headphone Playback Volume", RT5645_HP_VOL,
8101319b2f6SOder Chiou RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv),
8111319b2f6SOder Chiou
8121319b2f6SOder Chiou /* OUTPUT Control */
8131319b2f6SOder Chiou SOC_DOUBLE("OUT Playback Switch", RT5645_LOUT1,
8141319b2f6SOder Chiou RT5645_L_MUTE_SFT, RT5645_R_MUTE_SFT, 1, 1),
8151319b2f6SOder Chiou SOC_DOUBLE("OUT Channel Switch", RT5645_LOUT1,
8161319b2f6SOder Chiou RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1),
8171319b2f6SOder Chiou SOC_DOUBLE_TLV("OUT Playback Volume", RT5645_LOUT1,
8181319b2f6SOder Chiou RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv),
8191319b2f6SOder Chiou
8201319b2f6SOder Chiou /* DAC Digital Volume */
8211319b2f6SOder Chiou SOC_DOUBLE("DAC2 Playback Switch", RT5645_DAC_CTRL,
8221319b2f6SOder Chiou RT5645_M_DAC_L2_VOL_SFT, RT5645_M_DAC_R2_VOL_SFT, 1, 1),
8231319b2f6SOder Chiou SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5645_DAC1_DIG_VOL,
824177e1e1fSBard Liao RT5645_L_VOL_SFT + 1, RT5645_R_VOL_SFT + 1, 87, 0, dac_vol_tlv),
8251319b2f6SOder Chiou SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5645_DAC2_DIG_VOL,
826177e1e1fSBard Liao RT5645_L_VOL_SFT + 1, RT5645_R_VOL_SFT + 1, 87, 0, dac_vol_tlv),
8271319b2f6SOder Chiou
8281319b2f6SOder Chiou /* IN1/IN2 Control */
8291319b2f6SOder Chiou SOC_SINGLE_TLV("IN1 Boost", RT5645_IN1_CTRL1,
830b28785faSBard Liao RT5645_BST_SFT1, 12, 0, bst_tlv),
8311319b2f6SOder Chiou SOC_SINGLE_TLV("IN2 Boost", RT5645_IN2_CTRL,
8321319b2f6SOder Chiou RT5645_BST_SFT2, 8, 0, bst_tlv),
8331319b2f6SOder Chiou
8341319b2f6SOder Chiou /* INL/INR Volume Control */
8351319b2f6SOder Chiou SOC_DOUBLE_TLV("IN Capture Volume", RT5645_INL1_INR1_VOL,
8361319b2f6SOder Chiou RT5645_INL_VOL_SFT, RT5645_INR_VOL_SFT, 31, 1, in_vol_tlv),
8371319b2f6SOder Chiou
8381319b2f6SOder Chiou /* ADC Digital Volume Control */
8391319b2f6SOder Chiou SOC_DOUBLE("ADC Capture Switch", RT5645_STO1_ADC_DIG_VOL,
8401319b2f6SOder Chiou RT5645_L_MUTE_SFT, RT5645_R_MUTE_SFT, 1, 1),
8411319b2f6SOder Chiou SOC_DOUBLE_TLV("ADC Capture Volume", RT5645_STO1_ADC_DIG_VOL,
842177e1e1fSBard Liao RT5645_L_VOL_SFT + 1, RT5645_R_VOL_SFT + 1, 63, 0, adc_vol_tlv),
8431319b2f6SOder Chiou SOC_DOUBLE("Mono ADC Capture Switch", RT5645_MONO_ADC_DIG_VOL,
8441319b2f6SOder Chiou RT5645_L_MUTE_SFT, RT5645_R_MUTE_SFT, 1, 1),
8451319b2f6SOder Chiou SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT5645_MONO_ADC_DIG_VOL,
846177e1e1fSBard Liao RT5645_L_VOL_SFT + 1, RT5645_R_VOL_SFT + 1, 63, 0, adc_vol_tlv),
8471319b2f6SOder Chiou
8481319b2f6SOder Chiou /* ADC Boost Volume Control */
8498c1a9d63SOder Chiou SOC_DOUBLE_TLV("ADC Boost Capture Volume", RT5645_ADC_BST_VOL1,
8501319b2f6SOder Chiou RT5645_STO1_ADC_L_BST_SFT, RT5645_STO1_ADC_R_BST_SFT, 3, 0,
8511319b2f6SOder Chiou adc_bst_tlv),
8528c1a9d63SOder Chiou SOC_DOUBLE_TLV("Mono ADC Boost Capture Volume", RT5645_ADC_BST_VOL2,
8538c1a9d63SOder Chiou RT5645_MONO_ADC_L_BST_SFT, RT5645_MONO_ADC_R_BST_SFT, 3, 0,
8541319b2f6SOder Chiou adc_bst_tlv),
8551319b2f6SOder Chiou
8561319b2f6SOder Chiou /* I2S2 function select */
8571319b2f6SOder Chiou SOC_SINGLE("I2S2 Func Switch", RT5645_GPIO_CTRL1, RT5645_I2S2_SEL_SFT,
8581319b2f6SOder Chiou 1, 1),
859be77b38aSOder Chiou RT5645_HWEQ("Speaker HWEQ"),
860467b1479SBard Liao
861467b1479SBard Liao /* Digital Soft Volume Control */
862467b1479SBard Liao SOC_ENUM("DAC1 Digital Volume Control Func", rt5645_dac1_vol_ctrl_mode),
8631319b2f6SOder Chiou };
8641319b2f6SOder Chiou
8651319b2f6SOder Chiou /**
8661319b2f6SOder Chiou * set_dmic_clk - Set parameter of dmic.
8671319b2f6SOder Chiou *
8681319b2f6SOder Chiou * @w: DAPM widget.
8691319b2f6SOder Chiou * @kcontrol: The kcontrol of this widget.
8701319b2f6SOder Chiou * @event: Event id.
8711319b2f6SOder Chiou *
8721319b2f6SOder Chiou */
set_dmic_clk(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)8731319b2f6SOder Chiou static int set_dmic_clk(struct snd_soc_dapm_widget *w,
8741319b2f6SOder Chiou struct snd_kcontrol *kcontrol, int event)
8751319b2f6SOder Chiou {
87679223bf1SKuninori Morimoto struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
87779223bf1SKuninori Morimoto struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
87800a6d6e5SOder Chiou int idx, rate;
8791319b2f6SOder Chiou
88000a6d6e5SOder Chiou rate = rt5645->sysclk / rl6231_get_pre_div(rt5645->regmap,
88100a6d6e5SOder Chiou RT5645_ADDA_CLK1, RT5645_I2S_PD1_SFT);
88200a6d6e5SOder Chiou idx = rl6231_calc_dmic_clk(rate);
8831319b2f6SOder Chiou if (idx < 0)
88479223bf1SKuninori Morimoto dev_err(component->dev, "Failed to set DMIC clock\n");
8851319b2f6SOder Chiou else
88679223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_DMIC_CTRL1,
8871319b2f6SOder Chiou RT5645_DMIC_CLK_MASK, idx << RT5645_DMIC_CLK_SFT);
8881319b2f6SOder Chiou return idx;
8891319b2f6SOder Chiou }
8901319b2f6SOder Chiou
is_sys_clk_from_pll(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)8911319b2f6SOder Chiou static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
8921319b2f6SOder Chiou struct snd_soc_dapm_widget *sink)
8931319b2f6SOder Chiou {
89479223bf1SKuninori Morimoto struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
8951319b2f6SOder Chiou unsigned int val;
8961319b2f6SOder Chiou
897467a2553SKuninori Morimoto val = snd_soc_component_read(component, RT5645_GLB_CLK);
8981319b2f6SOder Chiou val &= RT5645_SCLK_SRC_MASK;
8991319b2f6SOder Chiou if (val == RT5645_SCLK_SRC_PLL1)
9001319b2f6SOder Chiou return 1;
9011319b2f6SOder Chiou else
9021319b2f6SOder Chiou return 0;
9031319b2f6SOder Chiou }
9041319b2f6SOder Chiou
is_using_asrc(struct snd_soc_dapm_widget * source,struct snd_soc_dapm_widget * sink)9059e268353SBard Liao static int is_using_asrc(struct snd_soc_dapm_widget *source,
9069e268353SBard Liao struct snd_soc_dapm_widget *sink)
9079e268353SBard Liao {
90879223bf1SKuninori Morimoto struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
9099e268353SBard Liao unsigned int reg, shift, val;
9109e268353SBard Liao
9119e268353SBard Liao switch (source->shift) {
9129e268353SBard Liao case 0:
9139e268353SBard Liao reg = RT5645_ASRC_3;
9149e268353SBard Liao shift = 0;
9159e268353SBard Liao break;
9169e268353SBard Liao case 1:
9179e268353SBard Liao reg = RT5645_ASRC_3;
9189e268353SBard Liao shift = 4;
9199e268353SBard Liao break;
9209e268353SBard Liao case 3:
9219e268353SBard Liao reg = RT5645_ASRC_2;
9229e268353SBard Liao shift = 0;
9239e268353SBard Liao break;
9249e268353SBard Liao case 8:
9259e268353SBard Liao reg = RT5645_ASRC_2;
9269e268353SBard Liao shift = 4;
9279e268353SBard Liao break;
9289e268353SBard Liao case 9:
9299e268353SBard Liao reg = RT5645_ASRC_2;
9309e268353SBard Liao shift = 8;
9319e268353SBard Liao break;
9329e268353SBard Liao case 10:
9339e268353SBard Liao reg = RT5645_ASRC_2;
9349e268353SBard Liao shift = 12;
9359e268353SBard Liao break;
9369e268353SBard Liao default:
9379e268353SBard Liao return 0;
9389e268353SBard Liao }
9399e268353SBard Liao
940467a2553SKuninori Morimoto val = (snd_soc_component_read(component, reg) >> shift) & 0xf;
9419e268353SBard Liao switch (val) {
9429e268353SBard Liao case 1:
9439e268353SBard Liao case 2:
9449e268353SBard Liao case 3:
9459e268353SBard Liao case 4:
9469e268353SBard Liao return 1;
9479e268353SBard Liao default:
9489e268353SBard Liao return 0;
9499e268353SBard Liao }
9509e268353SBard Liao
9519e268353SBard Liao }
9529e268353SBard Liao
rt5645_enable_hweq(struct snd_soc_component * component)95379223bf1SKuninori Morimoto static int rt5645_enable_hweq(struct snd_soc_component *component)
954be77b38aSOder Chiou {
95579223bf1SKuninori Morimoto struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
956be77b38aSOder Chiou int i;
957be77b38aSOder Chiou
958be77b38aSOder Chiou for (i = 0; i < RT5645_HWEQ_NUM; i++) {
959be77b38aSOder Chiou if (rt5645_validate_hweq(rt5645->eq_param[i].reg))
960be77b38aSOder Chiou regmap_write(rt5645->regmap, rt5645->eq_param[i].reg,
961be77b38aSOder Chiou rt5645->eq_param[i].val);
962be77b38aSOder Chiou else
963be77b38aSOder Chiou break;
964be77b38aSOder Chiou }
965be77b38aSOder Chiou
966be77b38aSOder Chiou return 0;
967be77b38aSOder Chiou }
968be77b38aSOder Chiou
96979080a8bSFang, Yang A /**
97079080a8bSFang, Yang A * rt5645_sel_asrc_clk_src - select ASRC clock source for a set of filters
97179223bf1SKuninori Morimoto * @component: SoC audio component device.
97279080a8bSFang, Yang A * @filter_mask: mask of filters.
97379080a8bSFang, Yang A * @clk_src: clock source
97479080a8bSFang, Yang A *
97579080a8bSFang, Yang A * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5645 can
97679080a8bSFang, Yang A * only support standard 32fs or 64fs i2s format, ASRC should be enabled to
97779080a8bSFang, Yang A * support special i2s clock format such as Intel's 100fs(100 * sampling rate).
97879080a8bSFang, Yang A * ASRC function will track i2s clock and generate a corresponding system clock
97979080a8bSFang, Yang A * for codec. This function provides an API to select the clock source for a
98079080a8bSFang, Yang A * set of filters specified by the mask. And the codec driver will turn on ASRC
98179080a8bSFang, Yang A * for these filters if ASRC is selected as their clock source.
98279080a8bSFang, Yang A */
rt5645_sel_asrc_clk_src(struct snd_soc_component * component,unsigned int filter_mask,unsigned int clk_src)98379223bf1SKuninori Morimoto int rt5645_sel_asrc_clk_src(struct snd_soc_component *component,
98479080a8bSFang, Yang A unsigned int filter_mask, unsigned int clk_src)
98579080a8bSFang, Yang A {
98679080a8bSFang, Yang A unsigned int asrc2_mask = 0;
98779080a8bSFang, Yang A unsigned int asrc2_value = 0;
98879080a8bSFang, Yang A unsigned int asrc3_mask = 0;
98979080a8bSFang, Yang A unsigned int asrc3_value = 0;
99079080a8bSFang, Yang A
99179080a8bSFang, Yang A switch (clk_src) {
99279080a8bSFang, Yang A case RT5645_CLK_SEL_SYS:
99379080a8bSFang, Yang A case RT5645_CLK_SEL_I2S1_ASRC:
99479080a8bSFang, Yang A case RT5645_CLK_SEL_I2S2_ASRC:
99579080a8bSFang, Yang A case RT5645_CLK_SEL_SYS2:
99679080a8bSFang, Yang A break;
99779080a8bSFang, Yang A
99879080a8bSFang, Yang A default:
99979080a8bSFang, Yang A return -EINVAL;
100079080a8bSFang, Yang A }
100179080a8bSFang, Yang A
100279080a8bSFang, Yang A if (filter_mask & RT5645_DA_STEREO_FILTER) {
100379080a8bSFang, Yang A asrc2_mask |= RT5645_DA_STO_CLK_SEL_MASK;
100479080a8bSFang, Yang A asrc2_value = (asrc2_value & ~RT5645_DA_STO_CLK_SEL_MASK)
100579080a8bSFang, Yang A | (clk_src << RT5645_DA_STO_CLK_SEL_SFT);
100679080a8bSFang, Yang A }
100779080a8bSFang, Yang A
100879080a8bSFang, Yang A if (filter_mask & RT5645_DA_MONO_L_FILTER) {
100979080a8bSFang, Yang A asrc2_mask |= RT5645_DA_MONOL_CLK_SEL_MASK;
101079080a8bSFang, Yang A asrc2_value = (asrc2_value & ~RT5645_DA_MONOL_CLK_SEL_MASK)
101179080a8bSFang, Yang A | (clk_src << RT5645_DA_MONOL_CLK_SEL_SFT);
101279080a8bSFang, Yang A }
101379080a8bSFang, Yang A
101479080a8bSFang, Yang A if (filter_mask & RT5645_DA_MONO_R_FILTER) {
101579080a8bSFang, Yang A asrc2_mask |= RT5645_DA_MONOR_CLK_SEL_MASK;
101679080a8bSFang, Yang A asrc2_value = (asrc2_value & ~RT5645_DA_MONOR_CLK_SEL_MASK)
101779080a8bSFang, Yang A | (clk_src << RT5645_DA_MONOR_CLK_SEL_SFT);
101879080a8bSFang, Yang A }
101979080a8bSFang, Yang A
102079080a8bSFang, Yang A if (filter_mask & RT5645_AD_STEREO_FILTER) {
102179080a8bSFang, Yang A asrc2_mask |= RT5645_AD_STO1_CLK_SEL_MASK;
102279080a8bSFang, Yang A asrc2_value = (asrc2_value & ~RT5645_AD_STO1_CLK_SEL_MASK)
102379080a8bSFang, Yang A | (clk_src << RT5645_AD_STO1_CLK_SEL_SFT);
102479080a8bSFang, Yang A }
102579080a8bSFang, Yang A
102679080a8bSFang, Yang A if (filter_mask & RT5645_AD_MONO_L_FILTER) {
102779080a8bSFang, Yang A asrc3_mask |= RT5645_AD_MONOL_CLK_SEL_MASK;
102879080a8bSFang, Yang A asrc3_value = (asrc3_value & ~RT5645_AD_MONOL_CLK_SEL_MASK)
102979080a8bSFang, Yang A | (clk_src << RT5645_AD_MONOL_CLK_SEL_SFT);
103079080a8bSFang, Yang A }
103179080a8bSFang, Yang A
103279080a8bSFang, Yang A if (filter_mask & RT5645_AD_MONO_R_FILTER) {
103379080a8bSFang, Yang A asrc3_mask |= RT5645_AD_MONOR_CLK_SEL_MASK;
103479080a8bSFang, Yang A asrc3_value = (asrc3_value & ~RT5645_AD_MONOR_CLK_SEL_MASK)
103579080a8bSFang, Yang A | (clk_src << RT5645_AD_MONOR_CLK_SEL_SFT);
103679080a8bSFang, Yang A }
103779080a8bSFang, Yang A
103879080a8bSFang, Yang A if (asrc2_mask)
103979223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_ASRC_2,
104079080a8bSFang, Yang A asrc2_mask, asrc2_value);
104179080a8bSFang, Yang A
104279080a8bSFang, Yang A if (asrc3_mask)
104379223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_ASRC_3,
104479080a8bSFang, Yang A asrc3_mask, asrc3_value);
104579080a8bSFang, Yang A
104679080a8bSFang, Yang A return 0;
104779080a8bSFang, Yang A }
104879080a8bSFang, Yang A EXPORT_SYMBOL_GPL(rt5645_sel_asrc_clk_src);
104979080a8bSFang, Yang A
10501319b2f6SOder Chiou /* Digital Mixer */
10511319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = {
10521319b2f6SOder Chiou SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER,
10531319b2f6SOder Chiou RT5645_M_ADC_L1_SFT, 1, 1),
10541319b2f6SOder Chiou SOC_DAPM_SINGLE("ADC2 Switch", RT5645_STO1_ADC_MIXER,
10551319b2f6SOder Chiou RT5645_M_ADC_L2_SFT, 1, 1),
10561319b2f6SOder Chiou };
10571319b2f6SOder Chiou
10581319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_sto1_adc_r_mix[] = {
10591319b2f6SOder Chiou SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER,
10601319b2f6SOder Chiou RT5645_M_ADC_R1_SFT, 1, 1),
10611319b2f6SOder Chiou SOC_DAPM_SINGLE("ADC2 Switch", RT5645_STO1_ADC_MIXER,
10621319b2f6SOder Chiou RT5645_M_ADC_R2_SFT, 1, 1),
10631319b2f6SOder Chiou };
10641319b2f6SOder Chiou
10651319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_mono_adc_l_mix[] = {
10661319b2f6SOder Chiou SOC_DAPM_SINGLE("ADC1 Switch", RT5645_MONO_ADC_MIXER,
10671319b2f6SOder Chiou RT5645_M_MONO_ADC_L1_SFT, 1, 1),
10681319b2f6SOder Chiou SOC_DAPM_SINGLE("ADC2 Switch", RT5645_MONO_ADC_MIXER,
10691319b2f6SOder Chiou RT5645_M_MONO_ADC_L2_SFT, 1, 1),
10701319b2f6SOder Chiou };
10711319b2f6SOder Chiou
10721319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_mono_adc_r_mix[] = {
10731319b2f6SOder Chiou SOC_DAPM_SINGLE("ADC1 Switch", RT5645_MONO_ADC_MIXER,
10741319b2f6SOder Chiou RT5645_M_MONO_ADC_R1_SFT, 1, 1),
10751319b2f6SOder Chiou SOC_DAPM_SINGLE("ADC2 Switch", RT5645_MONO_ADC_MIXER,
10761319b2f6SOder Chiou RT5645_M_MONO_ADC_R2_SFT, 1, 1),
10771319b2f6SOder Chiou };
10781319b2f6SOder Chiou
10791319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_dac_l_mix[] = {
10801319b2f6SOder Chiou SOC_DAPM_SINGLE("Stereo ADC Switch", RT5645_AD_DA_MIXER,
10811319b2f6SOder Chiou RT5645_M_ADCMIX_L_SFT, 1, 1),
108221cb13e7SOder Chiou SOC_DAPM_SINGLE_AUTODISABLE("DAC1 Switch", RT5645_AD_DA_MIXER,
10831319b2f6SOder Chiou RT5645_M_DAC1_L_SFT, 1, 1),
10841319b2f6SOder Chiou };
10851319b2f6SOder Chiou
10861319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_dac_r_mix[] = {
10871319b2f6SOder Chiou SOC_DAPM_SINGLE("Stereo ADC Switch", RT5645_AD_DA_MIXER,
10881319b2f6SOder Chiou RT5645_M_ADCMIX_R_SFT, 1, 1),
108921cb13e7SOder Chiou SOC_DAPM_SINGLE_AUTODISABLE("DAC1 Switch", RT5645_AD_DA_MIXER,
10901319b2f6SOder Chiou RT5645_M_DAC1_R_SFT, 1, 1),
10911319b2f6SOder Chiou };
10921319b2f6SOder Chiou
10931319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_sto_dac_l_mix[] = {
10941319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC L1 Switch", RT5645_STO_DAC_MIXER,
10951319b2f6SOder Chiou RT5645_M_DAC_L1_SFT, 1, 1),
10961319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC L2 Switch", RT5645_STO_DAC_MIXER,
10971319b2f6SOder Chiou RT5645_M_DAC_L2_SFT, 1, 1),
10981319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_STO_DAC_MIXER,
10991319b2f6SOder Chiou RT5645_M_DAC_R1_STO_L_SFT, 1, 1),
11001319b2f6SOder Chiou };
11011319b2f6SOder Chiou
11021319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_sto_dac_r_mix[] = {
11031319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_STO_DAC_MIXER,
11041319b2f6SOder Chiou RT5645_M_DAC_R1_SFT, 1, 1),
11051319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC R2 Switch", RT5645_STO_DAC_MIXER,
11061319b2f6SOder Chiou RT5645_M_DAC_R2_SFT, 1, 1),
11071319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC L1 Switch", RT5645_STO_DAC_MIXER,
11081319b2f6SOder Chiou RT5645_M_DAC_L1_STO_R_SFT, 1, 1),
11091319b2f6SOder Chiou };
11101319b2f6SOder Chiou
11111319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_mono_dac_l_mix[] = {
11121319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC L1 Switch", RT5645_MONO_DAC_MIXER,
11131319b2f6SOder Chiou RT5645_M_DAC_L1_MONO_L_SFT, 1, 1),
11141319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC L2 Switch", RT5645_MONO_DAC_MIXER,
11151319b2f6SOder Chiou RT5645_M_DAC_L2_MONO_L_SFT, 1, 1),
11161319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC R2 Switch", RT5645_MONO_DAC_MIXER,
11171319b2f6SOder Chiou RT5645_M_DAC_R2_MONO_L_SFT, 1, 1),
11181319b2f6SOder Chiou };
11191319b2f6SOder Chiou
11201319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_mono_dac_r_mix[] = {
11211319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_MONO_DAC_MIXER,
11221319b2f6SOder Chiou RT5645_M_DAC_R1_MONO_R_SFT, 1, 1),
11231319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC R2 Switch", RT5645_MONO_DAC_MIXER,
11241319b2f6SOder Chiou RT5645_M_DAC_R2_MONO_R_SFT, 1, 1),
11251319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC L2 Switch", RT5645_MONO_DAC_MIXER,
11261319b2f6SOder Chiou RT5645_M_DAC_L2_MONO_R_SFT, 1, 1),
11271319b2f6SOder Chiou };
11281319b2f6SOder Chiou
11291319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_dig_l_mix[] = {
11301319b2f6SOder Chiou SOC_DAPM_SINGLE("Sto DAC Mix L Switch", RT5645_DIG_MIXER,
11311319b2f6SOder Chiou RT5645_M_STO_L_DAC_L_SFT, 1, 1),
11321319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC L2 Switch", RT5645_DIG_MIXER,
11331319b2f6SOder Chiou RT5645_M_DAC_L2_DAC_L_SFT, 1, 1),
11341319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC R2 Switch", RT5645_DIG_MIXER,
11351319b2f6SOder Chiou RT5645_M_DAC_R2_DAC_L_SFT, 1, 1),
11361319b2f6SOder Chiou };
11371319b2f6SOder Chiou
11381319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_dig_r_mix[] = {
11391319b2f6SOder Chiou SOC_DAPM_SINGLE("Sto DAC Mix R Switch", RT5645_DIG_MIXER,
11401319b2f6SOder Chiou RT5645_M_STO_R_DAC_R_SFT, 1, 1),
11411319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC R2 Switch", RT5645_DIG_MIXER,
11421319b2f6SOder Chiou RT5645_M_DAC_R2_DAC_R_SFT, 1, 1),
11431319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC L2 Switch", RT5645_DIG_MIXER,
11441319b2f6SOder Chiou RT5645_M_DAC_L2_DAC_R_SFT, 1, 1),
11451319b2f6SOder Chiou };
11461319b2f6SOder Chiou
11471319b2f6SOder Chiou /* Analog Input Mixer */
11481319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_rec_l_mix[] = {
11491319b2f6SOder Chiou SOC_DAPM_SINGLE("HPOL Switch", RT5645_REC_L2_MIXER,
11501319b2f6SOder Chiou RT5645_M_HP_L_RM_L_SFT, 1, 1),
11511319b2f6SOder Chiou SOC_DAPM_SINGLE("INL Switch", RT5645_REC_L2_MIXER,
11521319b2f6SOder Chiou RT5645_M_IN_L_RM_L_SFT, 1, 1),
11531319b2f6SOder Chiou SOC_DAPM_SINGLE("BST2 Switch", RT5645_REC_L2_MIXER,
11541319b2f6SOder Chiou RT5645_M_BST2_RM_L_SFT, 1, 1),
11551319b2f6SOder Chiou SOC_DAPM_SINGLE("BST1 Switch", RT5645_REC_L2_MIXER,
11561319b2f6SOder Chiou RT5645_M_BST1_RM_L_SFT, 1, 1),
11571319b2f6SOder Chiou SOC_DAPM_SINGLE("OUT MIXL Switch", RT5645_REC_L2_MIXER,
11581319b2f6SOder Chiou RT5645_M_OM_L_RM_L_SFT, 1, 1),
11591319b2f6SOder Chiou };
11601319b2f6SOder Chiou
11611319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_rec_r_mix[] = {
11621319b2f6SOder Chiou SOC_DAPM_SINGLE("HPOR Switch", RT5645_REC_R2_MIXER,
11631319b2f6SOder Chiou RT5645_M_HP_R_RM_R_SFT, 1, 1),
11641319b2f6SOder Chiou SOC_DAPM_SINGLE("INR Switch", RT5645_REC_R2_MIXER,
11651319b2f6SOder Chiou RT5645_M_IN_R_RM_R_SFT, 1, 1),
11661319b2f6SOder Chiou SOC_DAPM_SINGLE("BST2 Switch", RT5645_REC_R2_MIXER,
11671319b2f6SOder Chiou RT5645_M_BST2_RM_R_SFT, 1, 1),
11681319b2f6SOder Chiou SOC_DAPM_SINGLE("BST1 Switch", RT5645_REC_R2_MIXER,
11691319b2f6SOder Chiou RT5645_M_BST1_RM_R_SFT, 1, 1),
11701319b2f6SOder Chiou SOC_DAPM_SINGLE("OUT MIXR Switch", RT5645_REC_R2_MIXER,
11711319b2f6SOder Chiou RT5645_M_OM_R_RM_R_SFT, 1, 1),
11721319b2f6SOder Chiou };
11731319b2f6SOder Chiou
11741319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_spk_l_mix[] = {
11751319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC L1 Switch", RT5645_SPK_L_MIXER,
11761319b2f6SOder Chiou RT5645_M_DAC_L1_SM_L_SFT, 1, 1),
11771319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC L2 Switch", RT5645_SPK_L_MIXER,
11781319b2f6SOder Chiou RT5645_M_DAC_L2_SM_L_SFT, 1, 1),
11791319b2f6SOder Chiou SOC_DAPM_SINGLE("INL Switch", RT5645_SPK_L_MIXER,
11801319b2f6SOder Chiou RT5645_M_IN_L_SM_L_SFT, 1, 1),
11811319b2f6SOder Chiou SOC_DAPM_SINGLE("BST1 Switch", RT5645_SPK_L_MIXER,
11821319b2f6SOder Chiou RT5645_M_BST1_L_SM_L_SFT, 1, 1),
11831319b2f6SOder Chiou };
11841319b2f6SOder Chiou
11851319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_spk_r_mix[] = {
11861319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_SPK_R_MIXER,
11871319b2f6SOder Chiou RT5645_M_DAC_R1_SM_R_SFT, 1, 1),
11881319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC R2 Switch", RT5645_SPK_R_MIXER,
11891319b2f6SOder Chiou RT5645_M_DAC_R2_SM_R_SFT, 1, 1),
11901319b2f6SOder Chiou SOC_DAPM_SINGLE("INR Switch", RT5645_SPK_R_MIXER,
11911319b2f6SOder Chiou RT5645_M_IN_R_SM_R_SFT, 1, 1),
11921319b2f6SOder Chiou SOC_DAPM_SINGLE("BST2 Switch", RT5645_SPK_R_MIXER,
11931319b2f6SOder Chiou RT5645_M_BST2_R_SM_R_SFT, 1, 1),
11941319b2f6SOder Chiou };
11951319b2f6SOder Chiou
11961319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_out_l_mix[] = {
11971319b2f6SOder Chiou SOC_DAPM_SINGLE("BST1 Switch", RT5645_OUT_L1_MIXER,
11981319b2f6SOder Chiou RT5645_M_BST1_OM_L_SFT, 1, 1),
11991319b2f6SOder Chiou SOC_DAPM_SINGLE("INL Switch", RT5645_OUT_L1_MIXER,
12001319b2f6SOder Chiou RT5645_M_IN_L_OM_L_SFT, 1, 1),
12011319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC L2 Switch", RT5645_OUT_L1_MIXER,
12021319b2f6SOder Chiou RT5645_M_DAC_L2_OM_L_SFT, 1, 1),
12031319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC L1 Switch", RT5645_OUT_L1_MIXER,
12041319b2f6SOder Chiou RT5645_M_DAC_L1_OM_L_SFT, 1, 1),
12051319b2f6SOder Chiou };
12061319b2f6SOder Chiou
12071319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_out_r_mix[] = {
12081319b2f6SOder Chiou SOC_DAPM_SINGLE("BST2 Switch", RT5645_OUT_R1_MIXER,
12091319b2f6SOder Chiou RT5645_M_BST2_OM_R_SFT, 1, 1),
12101319b2f6SOder Chiou SOC_DAPM_SINGLE("INR Switch", RT5645_OUT_R1_MIXER,
12111319b2f6SOder Chiou RT5645_M_IN_R_OM_R_SFT, 1, 1),
12121319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC R2 Switch", RT5645_OUT_R1_MIXER,
12131319b2f6SOder Chiou RT5645_M_DAC_R2_OM_R_SFT, 1, 1),
12141319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_OUT_R1_MIXER,
12151319b2f6SOder Chiou RT5645_M_DAC_R1_OM_R_SFT, 1, 1),
12161319b2f6SOder Chiou };
12171319b2f6SOder Chiou
12181319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_spo_l_mix[] = {
12191319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_SPO_MIXER,
12201319b2f6SOder Chiou RT5645_M_DAC_R1_SPM_L_SFT, 1, 1),
12211319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC L1 Switch", RT5645_SPO_MIXER,
12221319b2f6SOder Chiou RT5645_M_DAC_L1_SPM_L_SFT, 1, 1),
12231319b2f6SOder Chiou SOC_DAPM_SINGLE("SPKVOL R Switch", RT5645_SPO_MIXER,
12241319b2f6SOder Chiou RT5645_M_SV_R_SPM_L_SFT, 1, 1),
12251319b2f6SOder Chiou SOC_DAPM_SINGLE("SPKVOL L Switch", RT5645_SPO_MIXER,
12261319b2f6SOder Chiou RT5645_M_SV_L_SPM_L_SFT, 1, 1),
12271319b2f6SOder Chiou };
12281319b2f6SOder Chiou
12291319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_spo_r_mix[] = {
12301319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_SPO_MIXER,
12311319b2f6SOder Chiou RT5645_M_DAC_R1_SPM_R_SFT, 1, 1),
12321319b2f6SOder Chiou SOC_DAPM_SINGLE("SPKVOL R Switch", RT5645_SPO_MIXER,
12331319b2f6SOder Chiou RT5645_M_SV_R_SPM_R_SFT, 1, 1),
12341319b2f6SOder Chiou };
12351319b2f6SOder Chiou
12361319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_hpo_mix[] = {
12371319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC1 Switch", RT5645_HPO_MIXER,
12381319b2f6SOder Chiou RT5645_M_DAC1_HM_SFT, 1, 1),
12391319b2f6SOder Chiou SOC_DAPM_SINGLE("HPVOL Switch", RT5645_HPO_MIXER,
12401319b2f6SOder Chiou RT5645_M_HPVOL_HM_SFT, 1, 1),
12411319b2f6SOder Chiou };
12421319b2f6SOder Chiou
12431319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_hpvoll_mix[] = {
12441319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC1 Switch", RT5645_HPOMIXL_CTRL,
12451319b2f6SOder Chiou RT5645_M_DAC1_HV_SFT, 1, 1),
12461319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC2 Switch", RT5645_HPOMIXL_CTRL,
12471319b2f6SOder Chiou RT5645_M_DAC2_HV_SFT, 1, 1),
12481319b2f6SOder Chiou SOC_DAPM_SINGLE("INL Switch", RT5645_HPOMIXL_CTRL,
12491319b2f6SOder Chiou RT5645_M_IN_HV_SFT, 1, 1),
12501319b2f6SOder Chiou SOC_DAPM_SINGLE("BST1 Switch", RT5645_HPOMIXL_CTRL,
12511319b2f6SOder Chiou RT5645_M_BST1_HV_SFT, 1, 1),
12521319b2f6SOder Chiou };
12531319b2f6SOder Chiou
12541319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_hpvolr_mix[] = {
12551319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC1 Switch", RT5645_HPOMIXR_CTRL,
12561319b2f6SOder Chiou RT5645_M_DAC1_HV_SFT, 1, 1),
12571319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC2 Switch", RT5645_HPOMIXR_CTRL,
12581319b2f6SOder Chiou RT5645_M_DAC2_HV_SFT, 1, 1),
12591319b2f6SOder Chiou SOC_DAPM_SINGLE("INR Switch", RT5645_HPOMIXR_CTRL,
12601319b2f6SOder Chiou RT5645_M_IN_HV_SFT, 1, 1),
12611319b2f6SOder Chiou SOC_DAPM_SINGLE("BST2 Switch", RT5645_HPOMIXR_CTRL,
12621319b2f6SOder Chiou RT5645_M_BST2_HV_SFT, 1, 1),
12631319b2f6SOder Chiou };
12641319b2f6SOder Chiou
12651319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_lout_mix[] = {
12661319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC L1 Switch", RT5645_LOUT_MIXER,
12671319b2f6SOder Chiou RT5645_M_DAC_L1_LM_SFT, 1, 1),
12681319b2f6SOder Chiou SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_LOUT_MIXER,
12691319b2f6SOder Chiou RT5645_M_DAC_R1_LM_SFT, 1, 1),
12701319b2f6SOder Chiou SOC_DAPM_SINGLE("OUTMIX L Switch", RT5645_LOUT_MIXER,
12711319b2f6SOder Chiou RT5645_M_OV_L_LM_SFT, 1, 1),
12721319b2f6SOder Chiou SOC_DAPM_SINGLE("OUTMIX R Switch", RT5645_LOUT_MIXER,
12731319b2f6SOder Chiou RT5645_M_OV_R_LM_SFT, 1, 1),
12741319b2f6SOder Chiou };
12751319b2f6SOder Chiou
12761319b2f6SOder Chiou /*DAC1 L/R source*/ /* MX-29 [9:8] [11:10] */
12771319b2f6SOder Chiou static const char * const rt5645_dac1_src[] = {
12781319b2f6SOder Chiou "IF1 DAC", "IF2 DAC", "IF3 DAC"
12791319b2f6SOder Chiou };
12801319b2f6SOder Chiou
12811319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
12821319b2f6SOder Chiou rt5645_dac1l_enum, RT5645_AD_DA_MIXER,
12831319b2f6SOder Chiou RT5645_DAC1_L_SEL_SFT, rt5645_dac1_src);
12841319b2f6SOder Chiou
12851319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_dac1l_mux =
12861319b2f6SOder Chiou SOC_DAPM_ENUM("DAC1 L source", rt5645_dac1l_enum);
12871319b2f6SOder Chiou
12881319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
12891319b2f6SOder Chiou rt5645_dac1r_enum, RT5645_AD_DA_MIXER,
12901319b2f6SOder Chiou RT5645_DAC1_R_SEL_SFT, rt5645_dac1_src);
12911319b2f6SOder Chiou
12921319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_dac1r_mux =
12931319b2f6SOder Chiou SOC_DAPM_ENUM("DAC1 R source", rt5645_dac1r_enum);
12941319b2f6SOder Chiou
12951319b2f6SOder Chiou /*DAC2 L/R source*/ /* MX-1B [6:4] [2:0] */
12961319b2f6SOder Chiou static const char * const rt5645_dac12_src[] = {
12971319b2f6SOder Chiou "IF1 DAC", "IF2 DAC", "IF3 DAC", "Mono ADC", "VAD_ADC"
12981319b2f6SOder Chiou };
12991319b2f6SOder Chiou
13001319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
13011319b2f6SOder Chiou rt5645_dac2l_enum, RT5645_DAC_CTRL,
13021319b2f6SOder Chiou RT5645_DAC2_L_SEL_SFT, rt5645_dac12_src);
13031319b2f6SOder Chiou
13041319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_dac_l2_mux =
13051319b2f6SOder Chiou SOC_DAPM_ENUM("DAC2 L source", rt5645_dac2l_enum);
13061319b2f6SOder Chiou
13071319b2f6SOder Chiou static const char * const rt5645_dacr2_src[] = {
13081319b2f6SOder Chiou "IF1 DAC", "IF2 DAC", "IF3 DAC", "Mono ADC", "Haptic"
13091319b2f6SOder Chiou };
13101319b2f6SOder Chiou
13111319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
13121319b2f6SOder Chiou rt5645_dac2r_enum, RT5645_DAC_CTRL,
13131319b2f6SOder Chiou RT5645_DAC2_R_SEL_SFT, rt5645_dacr2_src);
13141319b2f6SOder Chiou
13151319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_dac_r2_mux =
13161319b2f6SOder Chiou SOC_DAPM_ENUM("DAC2 R source", rt5645_dac2r_enum);
13171319b2f6SOder Chiou
13181319b2f6SOder Chiou /* Stereo1 ADC source */
13191319b2f6SOder Chiou /* MX-27 [12] */
13201319b2f6SOder Chiou static const char * const rt5645_stereo_adc1_src[] = {
13211319b2f6SOder Chiou "DAC MIX", "ADC"
13221319b2f6SOder Chiou };
13231319b2f6SOder Chiou
13241319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
13251319b2f6SOder Chiou rt5645_stereo1_adc1_enum, RT5645_STO1_ADC_MIXER,
13261319b2f6SOder Chiou RT5645_ADC_1_SRC_SFT, rt5645_stereo_adc1_src);
13271319b2f6SOder Chiou
13281319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_sto_adc1_mux =
13291319b2f6SOder Chiou SOC_DAPM_ENUM("Stereo1 ADC1 Mux", rt5645_stereo1_adc1_enum);
13301319b2f6SOder Chiou
13311319b2f6SOder Chiou /* MX-27 [11] */
13321319b2f6SOder Chiou static const char * const rt5645_stereo_adc2_src[] = {
13331319b2f6SOder Chiou "DAC MIX", "DMIC"
13341319b2f6SOder Chiou };
13351319b2f6SOder Chiou
13361319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
13371319b2f6SOder Chiou rt5645_stereo1_adc2_enum, RT5645_STO1_ADC_MIXER,
13381319b2f6SOder Chiou RT5645_ADC_2_SRC_SFT, rt5645_stereo_adc2_src);
13391319b2f6SOder Chiou
13401319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_sto_adc2_mux =
13411319b2f6SOder Chiou SOC_DAPM_ENUM("Stereo1 ADC2 Mux", rt5645_stereo1_adc2_enum);
13421319b2f6SOder Chiou
13431319b2f6SOder Chiou /* MX-27 [8] */
13441319b2f6SOder Chiou static const char * const rt5645_stereo_dmic_src[] = {
13451319b2f6SOder Chiou "DMIC1", "DMIC2"
13461319b2f6SOder Chiou };
13471319b2f6SOder Chiou
13481319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
13491319b2f6SOder Chiou rt5645_stereo1_dmic_enum, RT5645_STO1_ADC_MIXER,
13501319b2f6SOder Chiou RT5645_DMIC_SRC_SFT, rt5645_stereo_dmic_src);
13511319b2f6SOder Chiou
13521319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_sto1_dmic_mux =
13531319b2f6SOder Chiou SOC_DAPM_ENUM("Stereo1 DMIC source", rt5645_stereo1_dmic_enum);
13541319b2f6SOder Chiou
13551319b2f6SOder Chiou /* Mono ADC source */
13561319b2f6SOder Chiou /* MX-28 [12] */
13571319b2f6SOder Chiou static const char * const rt5645_mono_adc_l1_src[] = {
13581319b2f6SOder Chiou "Mono DAC MIXL", "ADC"
13591319b2f6SOder Chiou };
13601319b2f6SOder Chiou
13611319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
13621319b2f6SOder Chiou rt5645_mono_adc_l1_enum, RT5645_MONO_ADC_MIXER,
13631319b2f6SOder Chiou RT5645_MONO_ADC_L1_SRC_SFT, rt5645_mono_adc_l1_src);
13641319b2f6SOder Chiou
13651319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_mono_adc_l1_mux =
13661319b2f6SOder Chiou SOC_DAPM_ENUM("Mono ADC1 left source", rt5645_mono_adc_l1_enum);
13671319b2f6SOder Chiou /* MX-28 [11] */
13681319b2f6SOder Chiou static const char * const rt5645_mono_adc_l2_src[] = {
13691319b2f6SOder Chiou "Mono DAC MIXL", "DMIC"
13701319b2f6SOder Chiou };
13711319b2f6SOder Chiou
13721319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
13731319b2f6SOder Chiou rt5645_mono_adc_l2_enum, RT5645_MONO_ADC_MIXER,
13741319b2f6SOder Chiou RT5645_MONO_ADC_L2_SRC_SFT, rt5645_mono_adc_l2_src);
13751319b2f6SOder Chiou
13761319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_mono_adc_l2_mux =
13771319b2f6SOder Chiou SOC_DAPM_ENUM("Mono ADC2 left source", rt5645_mono_adc_l2_enum);
13781319b2f6SOder Chiou
13791319b2f6SOder Chiou /* MX-28 [8] */
13801319b2f6SOder Chiou static const char * const rt5645_mono_dmic_src[] = {
13811319b2f6SOder Chiou "DMIC1", "DMIC2"
13821319b2f6SOder Chiou };
13831319b2f6SOder Chiou
13841319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
13851319b2f6SOder Chiou rt5645_mono_dmic_l_enum, RT5645_MONO_ADC_MIXER,
13861319b2f6SOder Chiou RT5645_MONO_DMIC_L_SRC_SFT, rt5645_mono_dmic_src);
13871319b2f6SOder Chiou
13881319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_mono_dmic_l_mux =
13891319b2f6SOder Chiou SOC_DAPM_ENUM("Mono DMIC left source", rt5645_mono_dmic_l_enum);
13901319b2f6SOder Chiou /* MX-28 [1:0] */
13911319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
13921319b2f6SOder Chiou rt5645_mono_dmic_r_enum, RT5645_MONO_ADC_MIXER,
13931319b2f6SOder Chiou RT5645_MONO_DMIC_R_SRC_SFT, rt5645_mono_dmic_src);
13941319b2f6SOder Chiou
13951319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_mono_dmic_r_mux =
13961319b2f6SOder Chiou SOC_DAPM_ENUM("Mono DMIC Right source", rt5645_mono_dmic_r_enum);
13971319b2f6SOder Chiou /* MX-28 [4] */
13981319b2f6SOder Chiou static const char * const rt5645_mono_adc_r1_src[] = {
13991319b2f6SOder Chiou "Mono DAC MIXR", "ADC"
14001319b2f6SOder Chiou };
14011319b2f6SOder Chiou
14021319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
14031319b2f6SOder Chiou rt5645_mono_adc_r1_enum, RT5645_MONO_ADC_MIXER,
14041319b2f6SOder Chiou RT5645_MONO_ADC_R1_SRC_SFT, rt5645_mono_adc_r1_src);
14051319b2f6SOder Chiou
14061319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_mono_adc_r1_mux =
14071319b2f6SOder Chiou SOC_DAPM_ENUM("Mono ADC1 right source", rt5645_mono_adc_r1_enum);
14081319b2f6SOder Chiou /* MX-28 [3] */
14091319b2f6SOder Chiou static const char * const rt5645_mono_adc_r2_src[] = {
14101319b2f6SOder Chiou "Mono DAC MIXR", "DMIC"
14111319b2f6SOder Chiou };
14121319b2f6SOder Chiou
14131319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
14141319b2f6SOder Chiou rt5645_mono_adc_r2_enum, RT5645_MONO_ADC_MIXER,
14151319b2f6SOder Chiou RT5645_MONO_ADC_R2_SRC_SFT, rt5645_mono_adc_r2_src);
14161319b2f6SOder Chiou
14171319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_mono_adc_r2_mux =
14181319b2f6SOder Chiou SOC_DAPM_ENUM("Mono ADC2 right source", rt5645_mono_adc_r2_enum);
14191319b2f6SOder Chiou
14201319b2f6SOder Chiou /* MX-77 [9:8] */
14211319b2f6SOder Chiou static const char * const rt5645_if1_adc_in_src[] = {
142221ab3f2bSBard Liao "IF_ADC1/IF_ADC2/VAD_ADC", "IF_ADC2/IF_ADC1/VAD_ADC",
142321ab3f2bSBard Liao "VAD_ADC/IF_ADC1/IF_ADC2", "VAD_ADC/IF_ADC2/IF_ADC1"
14241319b2f6SOder Chiou };
14251319b2f6SOder Chiou
14261319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
14271319b2f6SOder Chiou rt5645_if1_adc_in_enum, RT5645_TDM_CTRL_1,
14281319b2f6SOder Chiou RT5645_IF1_ADC_IN_SFT, rt5645_if1_adc_in_src);
14291319b2f6SOder Chiou
14301319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_if1_adc_in_mux =
14311319b2f6SOder Chiou SOC_DAPM_ENUM("IF1 ADC IN source", rt5645_if1_adc_in_enum);
14321319b2f6SOder Chiou
143321ab3f2bSBard Liao /* MX-78 [4:0] */
143421ab3f2bSBard Liao static const char * const rt5650_if1_adc_in_src[] = {
143521ab3f2bSBard Liao "IF_ADC1/IF_ADC2/DAC_REF/Null",
143621ab3f2bSBard Liao "IF_ADC1/IF_ADC2/Null/DAC_REF",
143721ab3f2bSBard Liao "IF_ADC1/DAC_REF/IF_ADC2/Null",
143821ab3f2bSBard Liao "IF_ADC1/DAC_REF/Null/IF_ADC2",
143921ab3f2bSBard Liao "IF_ADC1/Null/DAC_REF/IF_ADC2",
144021ab3f2bSBard Liao "IF_ADC1/Null/IF_ADC2/DAC_REF",
144121ab3f2bSBard Liao
144221ab3f2bSBard Liao "IF_ADC2/IF_ADC1/DAC_REF/Null",
144321ab3f2bSBard Liao "IF_ADC2/IF_ADC1/Null/DAC_REF",
144421ab3f2bSBard Liao "IF_ADC2/DAC_REF/IF_ADC1/Null",
144521ab3f2bSBard Liao "IF_ADC2/DAC_REF/Null/IF_ADC1",
144621ab3f2bSBard Liao "IF_ADC2/Null/DAC_REF/IF_ADC1",
144721ab3f2bSBard Liao "IF_ADC2/Null/IF_ADC1/DAC_REF",
144821ab3f2bSBard Liao
144921ab3f2bSBard Liao "DAC_REF/IF_ADC1/IF_ADC2/Null",
145021ab3f2bSBard Liao "DAC_REF/IF_ADC1/Null/IF_ADC2",
145121ab3f2bSBard Liao "DAC_REF/IF_ADC2/IF_ADC1/Null",
145221ab3f2bSBard Liao "DAC_REF/IF_ADC2/Null/IF_ADC1",
145321ab3f2bSBard Liao "DAC_REF/Null/IF_ADC1/IF_ADC2",
145421ab3f2bSBard Liao "DAC_REF/Null/IF_ADC2/IF_ADC1",
145521ab3f2bSBard Liao
145621ab3f2bSBard Liao "Null/IF_ADC1/IF_ADC2/DAC_REF",
145721ab3f2bSBard Liao "Null/IF_ADC1/DAC_REF/IF_ADC2",
145821ab3f2bSBard Liao "Null/IF_ADC2/IF_ADC1/DAC_REF",
145921ab3f2bSBard Liao "Null/IF_ADC2/DAC_REF/IF_ADC1",
146021ab3f2bSBard Liao "Null/DAC_REF/IF_ADC1/IF_ADC2",
146121ab3f2bSBard Liao "Null/DAC_REF/IF_ADC2/IF_ADC1",
146221ab3f2bSBard Liao };
146321ab3f2bSBard Liao
146421ab3f2bSBard Liao static SOC_ENUM_SINGLE_DECL(
146521ab3f2bSBard Liao rt5650_if1_adc_in_enum, RT5645_TDM_CTRL_2,
146621ab3f2bSBard Liao 0, rt5650_if1_adc_in_src);
146721ab3f2bSBard Liao
146821ab3f2bSBard Liao static const struct snd_kcontrol_new rt5650_if1_adc_in_mux =
146921ab3f2bSBard Liao SOC_DAPM_ENUM("IF1 ADC IN source", rt5650_if1_adc_in_enum);
147021ab3f2bSBard Liao
147121ab3f2bSBard Liao /* MX-78 [15:14][13:12][11:10] */
147221ab3f2bSBard Liao static const char * const rt5645_tdm_adc_swap_select[] = {
147321ab3f2bSBard Liao "L/R", "R/L", "L/L", "R/R"
147421ab3f2bSBard Liao };
147521ab3f2bSBard Liao
147621ab3f2bSBard Liao static SOC_ENUM_SINGLE_DECL(rt5650_tdm_adc_slot0_1_enum,
147721ab3f2bSBard Liao RT5645_TDM_CTRL_2, 14, rt5645_tdm_adc_swap_select);
147821ab3f2bSBard Liao
147921ab3f2bSBard Liao static const struct snd_kcontrol_new rt5650_if1_adc1_in_mux =
148021ab3f2bSBard Liao SOC_DAPM_ENUM("IF1 ADC1 IN source", rt5650_tdm_adc_slot0_1_enum);
148121ab3f2bSBard Liao
148221ab3f2bSBard Liao static SOC_ENUM_SINGLE_DECL(rt5650_tdm_adc_slot2_3_enum,
148321ab3f2bSBard Liao RT5645_TDM_CTRL_2, 12, rt5645_tdm_adc_swap_select);
148421ab3f2bSBard Liao
148521ab3f2bSBard Liao static const struct snd_kcontrol_new rt5650_if1_adc2_in_mux =
148621ab3f2bSBard Liao SOC_DAPM_ENUM("IF1 ADC2 IN source", rt5650_tdm_adc_slot2_3_enum);
148721ab3f2bSBard Liao
148821ab3f2bSBard Liao static SOC_ENUM_SINGLE_DECL(rt5650_tdm_adc_slot4_5_enum,
148921ab3f2bSBard Liao RT5645_TDM_CTRL_2, 10, rt5645_tdm_adc_swap_select);
149021ab3f2bSBard Liao
149121ab3f2bSBard Liao static const struct snd_kcontrol_new rt5650_if1_adc3_in_mux =
149221ab3f2bSBard Liao SOC_DAPM_ENUM("IF1 ADC3 IN source", rt5650_tdm_adc_slot4_5_enum);
149321ab3f2bSBard Liao
149421ab3f2bSBard Liao /* MX-77 [7:6][5:4][3:2] */
149521ab3f2bSBard Liao static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_slot0_1_enum,
149621ab3f2bSBard Liao RT5645_TDM_CTRL_1, 6, rt5645_tdm_adc_swap_select);
149721ab3f2bSBard Liao
149821ab3f2bSBard Liao static const struct snd_kcontrol_new rt5645_if1_adc1_in_mux =
149921ab3f2bSBard Liao SOC_DAPM_ENUM("IF1 ADC1 IN source", rt5645_tdm_adc_slot0_1_enum);
150021ab3f2bSBard Liao
150121ab3f2bSBard Liao static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_slot2_3_enum,
150221ab3f2bSBard Liao RT5645_TDM_CTRL_1, 4, rt5645_tdm_adc_swap_select);
150321ab3f2bSBard Liao
150421ab3f2bSBard Liao static const struct snd_kcontrol_new rt5645_if1_adc2_in_mux =
150521ab3f2bSBard Liao SOC_DAPM_ENUM("IF1 ADC2 IN source", rt5645_tdm_adc_slot2_3_enum);
150621ab3f2bSBard Liao
150721ab3f2bSBard Liao static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_slot4_5_enum,
150821ab3f2bSBard Liao RT5645_TDM_CTRL_1, 2, rt5645_tdm_adc_swap_select);
150921ab3f2bSBard Liao
151021ab3f2bSBard Liao static const struct snd_kcontrol_new rt5645_if1_adc3_in_mux =
151121ab3f2bSBard Liao SOC_DAPM_ENUM("IF1 ADC3 IN source", rt5645_tdm_adc_slot4_5_enum);
151221ab3f2bSBard Liao
151321ab3f2bSBard Liao /* MX-79 [14:12][10:8][6:4][2:0] */
151421ab3f2bSBard Liao static const char * const rt5645_tdm_dac_swap_select[] = {
151521ab3f2bSBard Liao "Slot0", "Slot1", "Slot2", "Slot3"
151621ab3f2bSBard Liao };
151721ab3f2bSBard Liao
151821ab3f2bSBard Liao static SOC_ENUM_SINGLE_DECL(rt5645_tdm_dac0_enum,
151921ab3f2bSBard Liao RT5645_TDM_CTRL_3, 12, rt5645_tdm_dac_swap_select);
152021ab3f2bSBard Liao
152121ab3f2bSBard Liao static const struct snd_kcontrol_new rt5645_if1_dac0_tdm_sel_mux =
152221ab3f2bSBard Liao SOC_DAPM_ENUM("IF1 DAC0 source", rt5645_tdm_dac0_enum);
152321ab3f2bSBard Liao
152421ab3f2bSBard Liao static SOC_ENUM_SINGLE_DECL(rt5645_tdm_dac1_enum,
152521ab3f2bSBard Liao RT5645_TDM_CTRL_3, 8, rt5645_tdm_dac_swap_select);
152621ab3f2bSBard Liao
152721ab3f2bSBard Liao static const struct snd_kcontrol_new rt5645_if1_dac1_tdm_sel_mux =
152821ab3f2bSBard Liao SOC_DAPM_ENUM("IF1 DAC1 source", rt5645_tdm_dac1_enum);
152921ab3f2bSBard Liao
153021ab3f2bSBard Liao static SOC_ENUM_SINGLE_DECL(rt5645_tdm_dac2_enum,
153121ab3f2bSBard Liao RT5645_TDM_CTRL_3, 4, rt5645_tdm_dac_swap_select);
153221ab3f2bSBard Liao
153321ab3f2bSBard Liao static const struct snd_kcontrol_new rt5645_if1_dac2_tdm_sel_mux =
153421ab3f2bSBard Liao SOC_DAPM_ENUM("IF1 DAC2 source", rt5645_tdm_dac2_enum);
153521ab3f2bSBard Liao
153621ab3f2bSBard Liao static SOC_ENUM_SINGLE_DECL(rt5645_tdm_dac3_enum,
153721ab3f2bSBard Liao RT5645_TDM_CTRL_3, 0, rt5645_tdm_dac_swap_select);
153821ab3f2bSBard Liao
153921ab3f2bSBard Liao static const struct snd_kcontrol_new rt5645_if1_dac3_tdm_sel_mux =
154021ab3f2bSBard Liao SOC_DAPM_ENUM("IF1 DAC3 source", rt5645_tdm_dac3_enum);
154121ab3f2bSBard Liao
154221ab3f2bSBard Liao /* MX-7a [14:12][10:8][6:4][2:0] */
154321ab3f2bSBard Liao static SOC_ENUM_SINGLE_DECL(rt5650_tdm_dac0_enum,
154421ab3f2bSBard Liao RT5650_TDM_CTRL_4, 12, rt5645_tdm_dac_swap_select);
154521ab3f2bSBard Liao
154621ab3f2bSBard Liao static const struct snd_kcontrol_new rt5650_if1_dac0_tdm_sel_mux =
154721ab3f2bSBard Liao SOC_DAPM_ENUM("IF1 DAC0 source", rt5650_tdm_dac0_enum);
154821ab3f2bSBard Liao
154921ab3f2bSBard Liao static SOC_ENUM_SINGLE_DECL(rt5650_tdm_dac1_enum,
155021ab3f2bSBard Liao RT5650_TDM_CTRL_4, 8, rt5645_tdm_dac_swap_select);
155121ab3f2bSBard Liao
155221ab3f2bSBard Liao static const struct snd_kcontrol_new rt5650_if1_dac1_tdm_sel_mux =
155321ab3f2bSBard Liao SOC_DAPM_ENUM("IF1 DAC1 source", rt5650_tdm_dac1_enum);
155421ab3f2bSBard Liao
155521ab3f2bSBard Liao static SOC_ENUM_SINGLE_DECL(rt5650_tdm_dac2_enum,
155621ab3f2bSBard Liao RT5650_TDM_CTRL_4, 4, rt5645_tdm_dac_swap_select);
155721ab3f2bSBard Liao
155821ab3f2bSBard Liao static const struct snd_kcontrol_new rt5650_if1_dac2_tdm_sel_mux =
155921ab3f2bSBard Liao SOC_DAPM_ENUM("IF1 DAC2 source", rt5650_tdm_dac2_enum);
156021ab3f2bSBard Liao
156121ab3f2bSBard Liao static SOC_ENUM_SINGLE_DECL(rt5650_tdm_dac3_enum,
156221ab3f2bSBard Liao RT5650_TDM_CTRL_4, 0, rt5645_tdm_dac_swap_select);
156321ab3f2bSBard Liao
156421ab3f2bSBard Liao static const struct snd_kcontrol_new rt5650_if1_dac3_tdm_sel_mux =
156521ab3f2bSBard Liao SOC_DAPM_ENUM("IF1 DAC3 source", rt5650_tdm_dac3_enum);
156621ab3f2bSBard Liao
15675c4ca99dSBard Liao /* MX-2d [3] [2] */
15685c4ca99dSBard Liao static const char * const rt5650_a_dac1_src[] = {
15695c4ca99dSBard Liao "DAC1", "Stereo DAC Mixer"
15705c4ca99dSBard Liao };
15715c4ca99dSBard Liao
15725c4ca99dSBard Liao static SOC_ENUM_SINGLE_DECL(
15735c4ca99dSBard Liao rt5650_a_dac1_l_enum, RT5650_A_DAC_SOUR,
15745c4ca99dSBard Liao RT5650_A_DAC1_L_IN_SFT, rt5650_a_dac1_src);
15755c4ca99dSBard Liao
15765c4ca99dSBard Liao static const struct snd_kcontrol_new rt5650_a_dac1_l_mux =
15775c4ca99dSBard Liao SOC_DAPM_ENUM("A DAC1 L source", rt5650_a_dac1_l_enum);
15785c4ca99dSBard Liao
15795c4ca99dSBard Liao static SOC_ENUM_SINGLE_DECL(
15805c4ca99dSBard Liao rt5650_a_dac1_r_enum, RT5650_A_DAC_SOUR,
15815c4ca99dSBard Liao RT5650_A_DAC1_R_IN_SFT, rt5650_a_dac1_src);
15825c4ca99dSBard Liao
15835c4ca99dSBard Liao static const struct snd_kcontrol_new rt5650_a_dac1_r_mux =
15845c4ca99dSBard Liao SOC_DAPM_ENUM("A DAC1 R source", rt5650_a_dac1_r_enum);
15855c4ca99dSBard Liao
15865c4ca99dSBard Liao /* MX-2d [1] [0] */
15875c4ca99dSBard Liao static const char * const rt5650_a_dac2_src[] = {
15885c4ca99dSBard Liao "Stereo DAC Mixer", "Mono DAC Mixer"
15895c4ca99dSBard Liao };
15905c4ca99dSBard Liao
15915c4ca99dSBard Liao static SOC_ENUM_SINGLE_DECL(
15925c4ca99dSBard Liao rt5650_a_dac2_l_enum, RT5650_A_DAC_SOUR,
15935c4ca99dSBard Liao RT5650_A_DAC2_L_IN_SFT, rt5650_a_dac2_src);
15945c4ca99dSBard Liao
15955c4ca99dSBard Liao static const struct snd_kcontrol_new rt5650_a_dac2_l_mux =
15965c4ca99dSBard Liao SOC_DAPM_ENUM("A DAC2 L source", rt5650_a_dac2_l_enum);
15975c4ca99dSBard Liao
15985c4ca99dSBard Liao static SOC_ENUM_SINGLE_DECL(
15995c4ca99dSBard Liao rt5650_a_dac2_r_enum, RT5650_A_DAC_SOUR,
16005c4ca99dSBard Liao RT5650_A_DAC2_R_IN_SFT, rt5650_a_dac2_src);
16015c4ca99dSBard Liao
16025c4ca99dSBard Liao static const struct snd_kcontrol_new rt5650_a_dac2_r_mux =
16035c4ca99dSBard Liao SOC_DAPM_ENUM("A DAC2 R source", rt5650_a_dac2_r_enum);
16045c4ca99dSBard Liao
16051319b2f6SOder Chiou /* MX-2F [13:12] */
16061319b2f6SOder Chiou static const char * const rt5645_if2_adc_in_src[] = {
16071319b2f6SOder Chiou "IF_ADC1", "IF_ADC2", "VAD_ADC"
16081319b2f6SOder Chiou };
16091319b2f6SOder Chiou
16101319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
16111319b2f6SOder Chiou rt5645_if2_adc_in_enum, RT5645_DIG_INF1_DATA,
16121319b2f6SOder Chiou RT5645_IF2_ADC_IN_SFT, rt5645_if2_adc_in_src);
16131319b2f6SOder Chiou
16141319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_if2_adc_in_mux =
16151319b2f6SOder Chiou SOC_DAPM_ENUM("IF2 ADC IN source", rt5645_if2_adc_in_enum);
16161319b2f6SOder Chiou
16171319b2f6SOder Chiou /* MX-31 [15] [13] [11] [9] */
16181319b2f6SOder Chiou static const char * const rt5645_pdm_src[] = {
16191319b2f6SOder Chiou "Mono DAC", "Stereo DAC"
16201319b2f6SOder Chiou };
16211319b2f6SOder Chiou
16221319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
16231319b2f6SOder Chiou rt5645_pdm1_l_enum, RT5645_PDM_OUT_CTRL,
16241319b2f6SOder Chiou RT5645_PDM1_L_SFT, rt5645_pdm_src);
16251319b2f6SOder Chiou
16261319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_pdm1_l_mux =
16271319b2f6SOder Chiou SOC_DAPM_ENUM("PDM1 L source", rt5645_pdm1_l_enum);
16281319b2f6SOder Chiou
16291319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
16301319b2f6SOder Chiou rt5645_pdm1_r_enum, RT5645_PDM_OUT_CTRL,
16311319b2f6SOder Chiou RT5645_PDM1_R_SFT, rt5645_pdm_src);
16321319b2f6SOder Chiou
16331319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_pdm1_r_mux =
16341319b2f6SOder Chiou SOC_DAPM_ENUM("PDM1 R source", rt5645_pdm1_r_enum);
16351319b2f6SOder Chiou
16361319b2f6SOder Chiou /* MX-9D [9:8] */
16371319b2f6SOder Chiou static const char * const rt5645_vad_adc_src[] = {
16381319b2f6SOder Chiou "Sto1 ADC L", "Mono ADC L", "Mono ADC R"
16391319b2f6SOder Chiou };
16401319b2f6SOder Chiou
16411319b2f6SOder Chiou static SOC_ENUM_SINGLE_DECL(
16421319b2f6SOder Chiou rt5645_vad_adc_enum, RT5645_VAD_CTRL4,
16431319b2f6SOder Chiou RT5645_VAD_SEL_SFT, rt5645_vad_adc_src);
16441319b2f6SOder Chiou
16451319b2f6SOder Chiou static const struct snd_kcontrol_new rt5645_vad_adc_mux =
16461319b2f6SOder Chiou SOC_DAPM_ENUM("VAD ADC source", rt5645_vad_adc_enum);
16471319b2f6SOder Chiou
16481319b2f6SOder Chiou static const struct snd_kcontrol_new spk_l_vol_control =
16491319b2f6SOder Chiou SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5645_SPK_VOL,
16501319b2f6SOder Chiou RT5645_L_MUTE_SFT, 1, 1);
16511319b2f6SOder Chiou
16521319b2f6SOder Chiou static const struct snd_kcontrol_new spk_r_vol_control =
16531319b2f6SOder Chiou SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5645_SPK_VOL,
16541319b2f6SOder Chiou RT5645_R_MUTE_SFT, 1, 1);
16551319b2f6SOder Chiou
16561319b2f6SOder Chiou static const struct snd_kcontrol_new hp_l_vol_control =
16571319b2f6SOder Chiou SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5645_HP_VOL,
16581319b2f6SOder Chiou RT5645_L_MUTE_SFT, 1, 1);
16591319b2f6SOder Chiou
16601319b2f6SOder Chiou static const struct snd_kcontrol_new hp_r_vol_control =
16611319b2f6SOder Chiou SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5645_HP_VOL,
16621319b2f6SOder Chiou RT5645_R_MUTE_SFT, 1, 1);
16631319b2f6SOder Chiou
16641319b2f6SOder Chiou static const struct snd_kcontrol_new pdm1_l_vol_control =
16651319b2f6SOder Chiou SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5645_PDM_OUT_CTRL,
16661319b2f6SOder Chiou RT5645_M_PDM1_L, 1, 1);
16671319b2f6SOder Chiou
16681319b2f6SOder Chiou static const struct snd_kcontrol_new pdm1_r_vol_control =
16691319b2f6SOder Chiou SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5645_PDM_OUT_CTRL,
16701319b2f6SOder Chiou RT5645_M_PDM1_R, 1, 1);
16711319b2f6SOder Chiou
hp_amp_power(struct snd_soc_component * component,int on)167279223bf1SKuninori Morimoto static void hp_amp_power(struct snd_soc_component *component, int on)
16731319b2f6SOder Chiou {
16741319b2f6SOder Chiou static int hp_amp_power_count;
167579223bf1SKuninori Morimoto struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
1676e9141c1aSOder Chiou int i, val;
16771319b2f6SOder Chiou
16781319b2f6SOder Chiou if (on) {
16791319b2f6SOder Chiou if (hp_amp_power_count <= 0) {
1680d12d6c4eSJohn Lin if (rt5645->codec_type == CODEC_TYPE_RT5650) {
168179223bf1SKuninori Morimoto snd_soc_component_write(component, RT5645_DEPOP_M2, 0x3100);
168279223bf1SKuninori Morimoto snd_soc_component_write(component, RT5645_CHARGE_PUMP,
1683d12d6c4eSJohn Lin 0x0e06);
168479223bf1SKuninori Morimoto snd_soc_component_write(component, RT5645_DEPOP_M1, 0x000d);
1685588cd850SOder Chiou regmap_write(rt5645->regmap, RT5645_PR_BASE +
1686588cd850SOder Chiou RT5645_HP_DCC_INT1, 0x9f01);
1687e9141c1aSOder Chiou for (i = 0; i < 20; i++) {
1688e9141c1aSOder Chiou usleep_range(1000, 1500);
1689e9141c1aSOder Chiou regmap_read(rt5645->regmap, RT5645_PR_BASE +
1690e9141c1aSOder Chiou RT5645_HP_DCC_INT1, &val);
1691e9141c1aSOder Chiou if (!(val & 0x8000))
1692e9141c1aSOder Chiou break;
1693e9141c1aSOder Chiou }
169479223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
1695588cd850SOder Chiou RT5645_HP_CO_MASK, RT5645_HP_CO_EN);
1696d12d6c4eSJohn Lin regmap_write(rt5645->regmap, RT5645_PR_BASE +
1697d12d6c4eSJohn Lin 0x3e, 0x7400);
169879223bf1SKuninori Morimoto snd_soc_component_write(component, RT5645_DEPOP_M3, 0x0737);
1699d12d6c4eSJohn Lin regmap_write(rt5645->regmap, RT5645_PR_BASE +
1700d12d6c4eSJohn Lin RT5645_MAMP_INT_REG2, 0xfc00);
170179223bf1SKuninori Morimoto snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1140);
1702aa98697cSShuming Fan snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
1703aa98697cSShuming Fan RT5645_PWR_HP_L | RT5645_PWR_HP_R,
1704aa98697cSShuming Fan RT5645_PWR_HP_L | RT5645_PWR_HP_R);
17053524be4bSJohn Lin msleep(90);
1706d12d6c4eSJohn Lin } else {
17071319b2f6SOder Chiou /* depop parameters */
170879223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_DEPOP_M2,
17091319b2f6SOder Chiou RT5645_DEPOP_MASK, RT5645_DEPOP_MAN);
171079223bf1SKuninori Morimoto snd_soc_component_write(component, RT5645_DEPOP_M1, 0x000d);
17111319b2f6SOder Chiou regmap_write(rt5645->regmap, RT5645_PR_BASE +
17121319b2f6SOder Chiou RT5645_HP_DCC_INT1, 0x9f01);
17131319b2f6SOder Chiou mdelay(150);
17141319b2f6SOder Chiou /* headphone amp power on */
171579223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
17161319b2f6SOder Chiou RT5645_PWR_FV1 | RT5645_PWR_FV2, 0);
171779223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_VOL,
17181319b2f6SOder Chiou RT5645_PWR_HV_L | RT5645_PWR_HV_R,
17191319b2f6SOder Chiou RT5645_PWR_HV_L | RT5645_PWR_HV_R);
172079223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
17211319b2f6SOder Chiou RT5645_PWR_HP_L | RT5645_PWR_HP_R |
17221319b2f6SOder Chiou RT5645_PWR_HA,
17231319b2f6SOder Chiou RT5645_PWR_HP_L | RT5645_PWR_HP_R |
17241319b2f6SOder Chiou RT5645_PWR_HA);
17251319b2f6SOder Chiou mdelay(5);
172679223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
17271319b2f6SOder Chiou RT5645_PWR_FV1 | RT5645_PWR_FV2,
17281319b2f6SOder Chiou RT5645_PWR_FV1 | RT5645_PWR_FV2);
17291319b2f6SOder Chiou
173079223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
17311319b2f6SOder Chiou RT5645_HP_CO_MASK | RT5645_HP_SG_MASK,
17321319b2f6SOder Chiou RT5645_HP_CO_EN | RT5645_HP_SG_EN);
17331319b2f6SOder Chiou regmap_write(rt5645->regmap, RT5645_PR_BASE +
17341319b2f6SOder Chiou 0x14, 0x1aaa);
17351319b2f6SOder Chiou regmap_write(rt5645->regmap, RT5645_PR_BASE +
17361319b2f6SOder Chiou 0x24, 0x0430);
17371319b2f6SOder Chiou }
1738d12d6c4eSJohn Lin }
17391319b2f6SOder Chiou hp_amp_power_count++;
17401319b2f6SOder Chiou } else {
17411319b2f6SOder Chiou hp_amp_power_count--;
17421319b2f6SOder Chiou if (hp_amp_power_count <= 0) {
1743d12d6c4eSJohn Lin if (rt5645->codec_type == CODEC_TYPE_RT5650) {
1744d12d6c4eSJohn Lin regmap_write(rt5645->regmap, RT5645_PR_BASE +
1745d12d6c4eSJohn Lin 0x3e, 0x7400);
174679223bf1SKuninori Morimoto snd_soc_component_write(component, RT5645_DEPOP_M3, 0x0737);
1747d12d6c4eSJohn Lin regmap_write(rt5645->regmap, RT5645_PR_BASE +
1748d12d6c4eSJohn Lin RT5645_MAMP_INT_REG2, 0xfc00);
174979223bf1SKuninori Morimoto snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1140);
1750d12d6c4eSJohn Lin msleep(100);
175179223bf1SKuninori Morimoto snd_soc_component_write(component, RT5645_DEPOP_M1, 0x0001);
1752aa98697cSShuming Fan snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
1753aa98697cSShuming Fan RT5645_PWR_HP_L | RT5645_PWR_HP_R, 0);
1754d12d6c4eSJohn Lin } else {
175579223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
1756d12d6c4eSJohn Lin RT5645_HP_SG_MASK |
1757d12d6c4eSJohn Lin RT5645_HP_L_SMT_MASK |
1758d12d6c4eSJohn Lin RT5645_HP_R_SMT_MASK,
1759d12d6c4eSJohn Lin RT5645_HP_SG_DIS |
1760d12d6c4eSJohn Lin RT5645_HP_L_SMT_DIS |
1761d12d6c4eSJohn Lin RT5645_HP_R_SMT_DIS);
17621319b2f6SOder Chiou /* headphone amp power down */
176379223bf1SKuninori Morimoto snd_soc_component_write(component, RT5645_DEPOP_M1, 0x0000);
176479223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
17651319b2f6SOder Chiou RT5645_PWR_HP_L | RT5645_PWR_HP_R |
17661319b2f6SOder Chiou RT5645_PWR_HA, 0);
176779223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_DEPOP_M2,
176837322551SBard Liao RT5645_DEPOP_MASK, 0);
17691319b2f6SOder Chiou }
17701319b2f6SOder Chiou }
17711319b2f6SOder Chiou }
1772d12d6c4eSJohn Lin }
17731319b2f6SOder Chiou
rt5645_hp_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)17741319b2f6SOder Chiou static int rt5645_hp_event(struct snd_soc_dapm_widget *w,
17751319b2f6SOder Chiou struct snd_kcontrol *kcontrol, int event)
17761319b2f6SOder Chiou {
177779223bf1SKuninori Morimoto struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
177879223bf1SKuninori Morimoto struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
17791319b2f6SOder Chiou
17801319b2f6SOder Chiou switch (event) {
17811319b2f6SOder Chiou case SND_SOC_DAPM_POST_PMU:
178279223bf1SKuninori Morimoto hp_amp_power(component, 1);
17831319b2f6SOder Chiou /* headphone unmute sequence */
1784d12d6c4eSJohn Lin if (rt5645->codec_type == CODEC_TYPE_RT5645) {
178579223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_DEPOP_M3,
17865c4ca99dSBard Liao RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK |
17875c4ca99dSBard Liao RT5645_CP_FQ3_MASK,
17881319b2f6SOder Chiou (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ1_SFT) |
17891319b2f6SOder Chiou (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) |
17901319b2f6SOder Chiou (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ3_SFT));
1791d12d6c4eSJohn Lin regmap_write(rt5645->regmap, RT5645_PR_BASE +
1792d12d6c4eSJohn Lin RT5645_MAMP_INT_REG2, 0xfc00);
179379223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
17941319b2f6SOder Chiou RT5645_SMT_TRIG_MASK, RT5645_SMT_TRIG_EN);
179579223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
17961319b2f6SOder Chiou RT5645_RSTN_MASK, RT5645_RSTN_EN);
179779223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
17981319b2f6SOder Chiou RT5645_RSTN_MASK | RT5645_HP_L_SMT_MASK |
17991319b2f6SOder Chiou RT5645_HP_R_SMT_MASK, RT5645_RSTN_DIS |
18001319b2f6SOder Chiou RT5645_HP_L_SMT_EN | RT5645_HP_R_SMT_EN);
18011319b2f6SOder Chiou msleep(40);
180279223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
18031319b2f6SOder Chiou RT5645_HP_SG_MASK | RT5645_HP_L_SMT_MASK |
18041319b2f6SOder Chiou RT5645_HP_R_SMT_MASK, RT5645_HP_SG_DIS |
18051319b2f6SOder Chiou RT5645_HP_L_SMT_DIS | RT5645_HP_R_SMT_DIS);
1806d12d6c4eSJohn Lin }
18071319b2f6SOder Chiou break;
18081319b2f6SOder Chiou
18091319b2f6SOder Chiou case SND_SOC_DAPM_PRE_PMD:
18101319b2f6SOder Chiou /* headphone mute sequence */
1811d12d6c4eSJohn Lin if (rt5645->codec_type == CODEC_TYPE_RT5645) {
181279223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_DEPOP_M3,
18131319b2f6SOder Chiou RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK |
18141319b2f6SOder Chiou RT5645_CP_FQ3_MASK,
18151319b2f6SOder Chiou (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ1_SFT) |
18161319b2f6SOder Chiou (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) |
18171319b2f6SOder Chiou (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ3_SFT));
1818d12d6c4eSJohn Lin regmap_write(rt5645->regmap, RT5645_PR_BASE +
1819d12d6c4eSJohn Lin RT5645_MAMP_INT_REG2, 0xfc00);
182079223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
18211319b2f6SOder Chiou RT5645_HP_SG_MASK, RT5645_HP_SG_EN);
182279223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
18231319b2f6SOder Chiou RT5645_RSTP_MASK, RT5645_RSTP_EN);
182479223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_DEPOP_M1,
18251319b2f6SOder Chiou RT5645_RSTP_MASK | RT5645_HP_L_SMT_MASK |
18261319b2f6SOder Chiou RT5645_HP_R_SMT_MASK, RT5645_RSTP_DIS |
18271319b2f6SOder Chiou RT5645_HP_L_SMT_EN | RT5645_HP_R_SMT_EN);
18281319b2f6SOder Chiou msleep(30);
1829d12d6c4eSJohn Lin }
183079223bf1SKuninori Morimoto hp_amp_power(component, 0);
18311319b2f6SOder Chiou break;
18321319b2f6SOder Chiou
18331319b2f6SOder Chiou default:
18341319b2f6SOder Chiou return 0;
18351319b2f6SOder Chiou }
18361319b2f6SOder Chiou
18371319b2f6SOder Chiou return 0;
18381319b2f6SOder Chiou }
18391319b2f6SOder Chiou
rt5645_spk_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)18401319b2f6SOder Chiou static int rt5645_spk_event(struct snd_soc_dapm_widget *w,
18411319b2f6SOder Chiou struct snd_kcontrol *kcontrol, int event)
18421319b2f6SOder Chiou {
184379223bf1SKuninori Morimoto struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
18441319b2f6SOder Chiou
18451319b2f6SOder Chiou switch (event) {
18461319b2f6SOder Chiou case SND_SOC_DAPM_POST_PMU:
184779223bf1SKuninori Morimoto rt5645_enable_hweq(component);
184879223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_DIG1,
18491319b2f6SOder Chiou RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
18501319b2f6SOder Chiou RT5645_PWR_CLS_D_L,
18511319b2f6SOder Chiou RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
18521319b2f6SOder Chiou RT5645_PWR_CLS_D_L);
185379223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_GEN_CTRL3,
1854ca8457bbSBard Liao RT5645_DET_CLK_MASK, RT5645_DET_CLK_MODE1);
18551319b2f6SOder Chiou break;
18561319b2f6SOder Chiou
18571319b2f6SOder Chiou case SND_SOC_DAPM_PRE_PMD:
185879223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_GEN_CTRL3,
1859ca8457bbSBard Liao RT5645_DET_CLK_MASK, RT5645_DET_CLK_DIS);
186079223bf1SKuninori Morimoto snd_soc_component_write(component, RT5645_EQ_CTRL2, 0);
186179223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_DIG1,
18621319b2f6SOder Chiou RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R |
18631319b2f6SOder Chiou RT5645_PWR_CLS_D_L, 0);
18641319b2f6SOder Chiou break;
18651319b2f6SOder Chiou
18661319b2f6SOder Chiou default:
18671319b2f6SOder Chiou return 0;
18681319b2f6SOder Chiou }
18691319b2f6SOder Chiou
18701319b2f6SOder Chiou return 0;
18711319b2f6SOder Chiou }
18721319b2f6SOder Chiou
rt5645_lout_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)18731319b2f6SOder Chiou static int rt5645_lout_event(struct snd_soc_dapm_widget *w,
18741319b2f6SOder Chiou struct snd_kcontrol *kcontrol, int event)
18751319b2f6SOder Chiou {
187679223bf1SKuninori Morimoto struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
18771319b2f6SOder Chiou
18781319b2f6SOder Chiou switch (event) {
18791319b2f6SOder Chiou case SND_SOC_DAPM_POST_PMU:
188079223bf1SKuninori Morimoto hp_amp_power(component, 1);
188179223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
18821319b2f6SOder Chiou RT5645_PWR_LM, RT5645_PWR_LM);
188379223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_LOUT1,
18841319b2f6SOder Chiou RT5645_L_MUTE | RT5645_R_MUTE, 0);
18851319b2f6SOder Chiou break;
18861319b2f6SOder Chiou
18871319b2f6SOder Chiou case SND_SOC_DAPM_PRE_PMD:
188879223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_LOUT1,
18891319b2f6SOder Chiou RT5645_L_MUTE | RT5645_R_MUTE,
18901319b2f6SOder Chiou RT5645_L_MUTE | RT5645_R_MUTE);
189179223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
18921319b2f6SOder Chiou RT5645_PWR_LM, 0);
189379223bf1SKuninori Morimoto hp_amp_power(component, 0);
18941319b2f6SOder Chiou break;
18951319b2f6SOder Chiou
18961319b2f6SOder Chiou default:
18971319b2f6SOder Chiou return 0;
18981319b2f6SOder Chiou }
18991319b2f6SOder Chiou
19001319b2f6SOder Chiou return 0;
19011319b2f6SOder Chiou }
19021319b2f6SOder Chiou
rt5645_bst2_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)19031319b2f6SOder Chiou static int rt5645_bst2_event(struct snd_soc_dapm_widget *w,
19041319b2f6SOder Chiou struct snd_kcontrol *kcontrol, int event)
19051319b2f6SOder Chiou {
190679223bf1SKuninori Morimoto struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
19071319b2f6SOder Chiou
19081319b2f6SOder Chiou switch (event) {
19091319b2f6SOder Chiou case SND_SOC_DAPM_POST_PMU:
191079223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_ANLG2,
19111319b2f6SOder Chiou RT5645_PWR_BST2_P, RT5645_PWR_BST2_P);
19121319b2f6SOder Chiou break;
19131319b2f6SOder Chiou
19141319b2f6SOder Chiou case SND_SOC_DAPM_PRE_PMD:
191579223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_ANLG2,
19161319b2f6SOder Chiou RT5645_PWR_BST2_P, 0);
19171319b2f6SOder Chiou break;
19181319b2f6SOder Chiou
19191319b2f6SOder Chiou default:
19201319b2f6SOder Chiou return 0;
19211319b2f6SOder Chiou }
19221319b2f6SOder Chiou
19231319b2f6SOder Chiou return 0;
19241319b2f6SOder Chiou }
19251319b2f6SOder Chiou
rt5645_set_micbias1_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * k,int event)1926e61f3f31SBard Liao static int rt5645_set_micbias1_event(struct snd_soc_dapm_widget *w,
1927e61f3f31SBard Liao struct snd_kcontrol *k, int event)
1928e61f3f31SBard Liao {
192979223bf1SKuninori Morimoto struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1930e61f3f31SBard Liao
1931e61f3f31SBard Liao switch (event) {
1932e61f3f31SBard Liao case SND_SOC_DAPM_PRE_PMU:
193379223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_GEN_CTRL2,
1934e61f3f31SBard Liao RT5645_MICBIAS1_POW_CTRL_SEL_MASK,
1935e61f3f31SBard Liao RT5645_MICBIAS1_POW_CTRL_SEL_M);
1936e61f3f31SBard Liao break;
1937e61f3f31SBard Liao
1938e61f3f31SBard Liao case SND_SOC_DAPM_POST_PMD:
193979223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_GEN_CTRL2,
1940e61f3f31SBard Liao RT5645_MICBIAS1_POW_CTRL_SEL_MASK,
1941e61f3f31SBard Liao RT5645_MICBIAS1_POW_CTRL_SEL_A);
1942e61f3f31SBard Liao break;
1943e61f3f31SBard Liao
1944e61f3f31SBard Liao default:
1945e61f3f31SBard Liao return 0;
1946e61f3f31SBard Liao }
1947e61f3f31SBard Liao
1948e61f3f31SBard Liao return 0;
1949e61f3f31SBard Liao }
1950e61f3f31SBard Liao
rt5645_set_micbias2_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * k,int event)1951e61f3f31SBard Liao static int rt5645_set_micbias2_event(struct snd_soc_dapm_widget *w,
1952e61f3f31SBard Liao struct snd_kcontrol *k, int event)
1953e61f3f31SBard Liao {
195479223bf1SKuninori Morimoto struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
1955e61f3f31SBard Liao
1956e61f3f31SBard Liao switch (event) {
1957e61f3f31SBard Liao case SND_SOC_DAPM_PRE_PMU:
195879223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_GEN_CTRL2,
1959e61f3f31SBard Liao RT5645_MICBIAS2_POW_CTRL_SEL_MASK,
1960e61f3f31SBard Liao RT5645_MICBIAS2_POW_CTRL_SEL_M);
1961e61f3f31SBard Liao break;
1962e61f3f31SBard Liao
1963e61f3f31SBard Liao case SND_SOC_DAPM_POST_PMD:
196479223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_GEN_CTRL2,
1965e61f3f31SBard Liao RT5645_MICBIAS2_POW_CTRL_SEL_MASK,
1966e61f3f31SBard Liao RT5645_MICBIAS2_POW_CTRL_SEL_A);
1967e61f3f31SBard Liao break;
1968e61f3f31SBard Liao
1969e61f3f31SBard Liao default:
1970e61f3f31SBard Liao return 0;
1971e61f3f31SBard Liao }
1972e61f3f31SBard Liao
1973e61f3f31SBard Liao return 0;
1974e61f3f31SBard Liao }
1975e61f3f31SBard Liao
19761319b2f6SOder Chiou static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = {
19771319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY("LDO2", RT5645_PWR_MIXER,
19781319b2f6SOder Chiou RT5645_PWR_LDO2_BIT, 0, NULL, 0),
19791319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY("PLL1", RT5645_PWR_ANLG2,
19801319b2f6SOder Chiou RT5645_PWR_PLL_BIT, 0, NULL, 0),
19811319b2f6SOder Chiou
19821319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY("JD Power", RT5645_PWR_ANLG2,
19831319b2f6SOder Chiou RT5645_PWR_JD1_BIT, 0, NULL, 0),
19841319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5645_PWR_VOL,
19851319b2f6SOder Chiou RT5645_PWR_MIC_DET_BIT, 0, NULL, 0),
19861319b2f6SOder Chiou
19879e268353SBard Liao /* ASRC */
19889e268353SBard Liao SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5645_ASRC_1,
19899e268353SBard Liao 11, 0, NULL, 0),
19909e268353SBard Liao SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5645_ASRC_1,
19919e268353SBard Liao 12, 0, NULL, 0),
19929e268353SBard Liao SND_SOC_DAPM_SUPPLY_S("DAC STO ASRC", 1, RT5645_ASRC_1,
19939e268353SBard Liao 10, 0, NULL, 0),
19949e268353SBard Liao SND_SOC_DAPM_SUPPLY_S("DAC MONO L ASRC", 1, RT5645_ASRC_1,
19959e268353SBard Liao 9, 0, NULL, 0),
19969e268353SBard Liao SND_SOC_DAPM_SUPPLY_S("DAC MONO R ASRC", 1, RT5645_ASRC_1,
19979e268353SBard Liao 8, 0, NULL, 0),
19989e268353SBard Liao SND_SOC_DAPM_SUPPLY_S("DMIC STO1 ASRC", 1, RT5645_ASRC_1,
19999e268353SBard Liao 7, 0, NULL, 0),
20009e268353SBard Liao SND_SOC_DAPM_SUPPLY_S("DMIC MONO L ASRC", 1, RT5645_ASRC_1,
20019e268353SBard Liao 5, 0, NULL, 0),
20029e268353SBard Liao SND_SOC_DAPM_SUPPLY_S("DMIC MONO R ASRC", 1, RT5645_ASRC_1,
20039e268353SBard Liao 4, 0, NULL, 0),
20049e268353SBard Liao SND_SOC_DAPM_SUPPLY_S("ADC STO1 ASRC", 1, RT5645_ASRC_1,
20059e268353SBard Liao 3, 0, NULL, 0),
20069e268353SBard Liao SND_SOC_DAPM_SUPPLY_S("ADC MONO L ASRC", 1, RT5645_ASRC_1,
20079e268353SBard Liao 1, 0, NULL, 0),
20089e268353SBard Liao SND_SOC_DAPM_SUPPLY_S("ADC MONO R ASRC", 1, RT5645_ASRC_1,
20099e268353SBard Liao 0, 0, NULL, 0),
20109e268353SBard Liao
20111319b2f6SOder Chiou /* Input Side */
20121319b2f6SOder Chiou /* micbias */
2013bd70b19eSBard Liao SND_SOC_DAPM_SUPPLY("micbias1", RT5645_PWR_ANLG2,
2014e61f3f31SBard Liao RT5645_PWR_MB1_BIT, 0, rt5645_set_micbias1_event,
2015e61f3f31SBard Liao SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
2016bd70b19eSBard Liao SND_SOC_DAPM_SUPPLY("micbias2", RT5645_PWR_ANLG2,
2017e61f3f31SBard Liao RT5645_PWR_MB2_BIT, 0, rt5645_set_micbias2_event,
2018e61f3f31SBard Liao SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
20191319b2f6SOder Chiou /* Input Lines */
20201319b2f6SOder Chiou SND_SOC_DAPM_INPUT("DMIC L1"),
20211319b2f6SOder Chiou SND_SOC_DAPM_INPUT("DMIC R1"),
20221319b2f6SOder Chiou SND_SOC_DAPM_INPUT("DMIC L2"),
20231319b2f6SOder Chiou SND_SOC_DAPM_INPUT("DMIC R2"),
20241319b2f6SOder Chiou
20251319b2f6SOder Chiou SND_SOC_DAPM_INPUT("IN1P"),
20261319b2f6SOder Chiou SND_SOC_DAPM_INPUT("IN1N"),
20271319b2f6SOder Chiou SND_SOC_DAPM_INPUT("IN2P"),
20281319b2f6SOder Chiou SND_SOC_DAPM_INPUT("IN2N"),
20291319b2f6SOder Chiou
20301319b2f6SOder Chiou SND_SOC_DAPM_INPUT("Haptic Generator"),
20311319b2f6SOder Chiou
20321319b2f6SOder Chiou SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0),
20331319b2f6SOder Chiou SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0),
20341319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0,
20351319b2f6SOder Chiou set_dmic_clk, SND_SOC_DAPM_PRE_PMU),
20361319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5645_DMIC_CTRL1,
20371319b2f6SOder Chiou RT5645_DMIC_1_EN_SFT, 0, NULL, 0),
20381319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5645_DMIC_CTRL1,
20391319b2f6SOder Chiou RT5645_DMIC_2_EN_SFT, 0, NULL, 0),
20401319b2f6SOder Chiou /* Boost */
20411319b2f6SOder Chiou SND_SOC_DAPM_PGA("BST1", RT5645_PWR_ANLG2,
20421319b2f6SOder Chiou RT5645_PWR_BST1_BIT, 0, NULL, 0),
20431319b2f6SOder Chiou SND_SOC_DAPM_PGA_E("BST2", RT5645_PWR_ANLG2,
20441319b2f6SOder Chiou RT5645_PWR_BST2_BIT, 0, NULL, 0, rt5645_bst2_event,
20451319b2f6SOder Chiou SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
20461319b2f6SOder Chiou /* Input Volume */
20471319b2f6SOder Chiou SND_SOC_DAPM_PGA("INL VOL", RT5645_PWR_VOL,
20481319b2f6SOder Chiou RT5645_PWR_IN_L_BIT, 0, NULL, 0),
20491319b2f6SOder Chiou SND_SOC_DAPM_PGA("INR VOL", RT5645_PWR_VOL,
20501319b2f6SOder Chiou RT5645_PWR_IN_R_BIT, 0, NULL, 0),
20511319b2f6SOder Chiou /* REC Mixer */
20521319b2f6SOder Chiou SND_SOC_DAPM_MIXER("RECMIXL", RT5645_PWR_MIXER, RT5645_PWR_RM_L_BIT,
20531319b2f6SOder Chiou 0, rt5645_rec_l_mix, ARRAY_SIZE(rt5645_rec_l_mix)),
20541319b2f6SOder Chiou SND_SOC_DAPM_MIXER("RECMIXR", RT5645_PWR_MIXER, RT5645_PWR_RM_R_BIT,
20551319b2f6SOder Chiou 0, rt5645_rec_r_mix, ARRAY_SIZE(rt5645_rec_r_mix)),
20561319b2f6SOder Chiou /* ADCs */
20571319b2f6SOder Chiou SND_SOC_DAPM_ADC("ADC L", NULL, SND_SOC_NOPM, 0, 0),
20581319b2f6SOder Chiou SND_SOC_DAPM_ADC("ADC R", NULL, SND_SOC_NOPM, 0, 0),
20591319b2f6SOder Chiou
20601319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY("ADC L power", RT5645_PWR_DIG1,
20611319b2f6SOder Chiou RT5645_PWR_ADC_L_BIT, 0, NULL, 0),
20621319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY("ADC R power", RT5645_PWR_DIG1,
20631319b2f6SOder Chiou RT5645_PWR_ADC_R_BIT, 0, NULL, 0),
20641319b2f6SOder Chiou
20651319b2f6SOder Chiou /* ADC Mux */
20661319b2f6SOder Chiou SND_SOC_DAPM_MUX("Stereo1 DMIC Mux", SND_SOC_NOPM, 0, 0,
20671319b2f6SOder Chiou &rt5645_sto1_dmic_mux),
20681319b2f6SOder Chiou SND_SOC_DAPM_MUX("Stereo1 ADC L2 Mux", SND_SOC_NOPM, 0, 0,
20691319b2f6SOder Chiou &rt5645_sto_adc2_mux),
20701319b2f6SOder Chiou SND_SOC_DAPM_MUX("Stereo1 ADC R2 Mux", SND_SOC_NOPM, 0, 0,
20711319b2f6SOder Chiou &rt5645_sto_adc2_mux),
20721319b2f6SOder Chiou SND_SOC_DAPM_MUX("Stereo1 ADC L1 Mux", SND_SOC_NOPM, 0, 0,
20731319b2f6SOder Chiou &rt5645_sto_adc1_mux),
20741319b2f6SOder Chiou SND_SOC_DAPM_MUX("Stereo1 ADC R1 Mux", SND_SOC_NOPM, 0, 0,
20751319b2f6SOder Chiou &rt5645_sto_adc1_mux),
20761319b2f6SOder Chiou SND_SOC_DAPM_MUX("Mono DMIC L Mux", SND_SOC_NOPM, 0, 0,
20771319b2f6SOder Chiou &rt5645_mono_dmic_l_mux),
20781319b2f6SOder Chiou SND_SOC_DAPM_MUX("Mono DMIC R Mux", SND_SOC_NOPM, 0, 0,
20791319b2f6SOder Chiou &rt5645_mono_dmic_r_mux),
20801319b2f6SOder Chiou SND_SOC_DAPM_MUX("Mono ADC L2 Mux", SND_SOC_NOPM, 0, 0,
20811319b2f6SOder Chiou &rt5645_mono_adc_l2_mux),
20821319b2f6SOder Chiou SND_SOC_DAPM_MUX("Mono ADC L1 Mux", SND_SOC_NOPM, 0, 0,
20831319b2f6SOder Chiou &rt5645_mono_adc_l1_mux),
20841319b2f6SOder Chiou SND_SOC_DAPM_MUX("Mono ADC R1 Mux", SND_SOC_NOPM, 0, 0,
20851319b2f6SOder Chiou &rt5645_mono_adc_r1_mux),
20861319b2f6SOder Chiou SND_SOC_DAPM_MUX("Mono ADC R2 Mux", SND_SOC_NOPM, 0, 0,
20871319b2f6SOder Chiou &rt5645_mono_adc_r2_mux),
20881319b2f6SOder Chiou /* ADC Mixer */
20891319b2f6SOder Chiou
20901319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY_S("adc stereo1 filter", 1, RT5645_PWR_DIG2,
20911319b2f6SOder Chiou RT5645_PWR_ADC_S1F_BIT, 0, NULL, 0),
20921319b2f6SOder Chiou SND_SOC_DAPM_MIXER_E("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0,
20931319b2f6SOder Chiou rt5645_sto1_adc_l_mix, ARRAY_SIZE(rt5645_sto1_adc_l_mix),
20941319b2f6SOder Chiou NULL, 0),
20951319b2f6SOder Chiou SND_SOC_DAPM_MIXER_E("Sto1 ADC MIXR", SND_SOC_NOPM, 0, 0,
20961319b2f6SOder Chiou rt5645_sto1_adc_r_mix, ARRAY_SIZE(rt5645_sto1_adc_r_mix),
20971319b2f6SOder Chiou NULL, 0),
20981319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY_S("adc mono left filter", 1, RT5645_PWR_DIG2,
20991319b2f6SOder Chiou RT5645_PWR_ADC_MF_L_BIT, 0, NULL, 0),
21001319b2f6SOder Chiou SND_SOC_DAPM_MIXER_E("Mono ADC MIXL", SND_SOC_NOPM, 0, 0,
21011319b2f6SOder Chiou rt5645_mono_adc_l_mix, ARRAY_SIZE(rt5645_mono_adc_l_mix),
21021319b2f6SOder Chiou NULL, 0),
21031319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY_S("adc mono right filter", 1, RT5645_PWR_DIG2,
21041319b2f6SOder Chiou RT5645_PWR_ADC_MF_R_BIT, 0, NULL, 0),
21051319b2f6SOder Chiou SND_SOC_DAPM_MIXER_E("Mono ADC MIXR", SND_SOC_NOPM, 0, 0,
21061319b2f6SOder Chiou rt5645_mono_adc_r_mix, ARRAY_SIZE(rt5645_mono_adc_r_mix),
21071319b2f6SOder Chiou NULL, 0),
21081319b2f6SOder Chiou
21091319b2f6SOder Chiou /* ADC PGA */
21101319b2f6SOder Chiou SND_SOC_DAPM_PGA("Stereo1 ADC MIXL", SND_SOC_NOPM, 0, 0, NULL, 0),
21111319b2f6SOder Chiou SND_SOC_DAPM_PGA("Stereo1 ADC MIXR", SND_SOC_NOPM, 0, 0, NULL, 0),
21121319b2f6SOder Chiou SND_SOC_DAPM_PGA("Sto2 ADC LR MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
21131319b2f6SOder Chiou SND_SOC_DAPM_PGA("VAD_ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
21141319b2f6SOder Chiou SND_SOC_DAPM_PGA("IF_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
21151319b2f6SOder Chiou SND_SOC_DAPM_PGA("IF_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
21161319b2f6SOder Chiou SND_SOC_DAPM_PGA("IF1_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0),
21171319b2f6SOder Chiou SND_SOC_DAPM_PGA("IF1_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0),
21181319b2f6SOder Chiou SND_SOC_DAPM_PGA("IF1_ADC3", SND_SOC_NOPM, 0, 0, NULL, 0),
21191319b2f6SOder Chiou SND_SOC_DAPM_PGA("IF1_ADC4", SND_SOC_NOPM, 0, 0, NULL, 0),
21201319b2f6SOder Chiou
21211319b2f6SOder Chiou /* IF1 2 Mux */
21221319b2f6SOder Chiou SND_SOC_DAPM_MUX("IF2 ADC Mux", SND_SOC_NOPM,
21231319b2f6SOder Chiou 0, 0, &rt5645_if2_adc_in_mux),
21241319b2f6SOder Chiou
21251319b2f6SOder Chiou /* Digital Interface */
21261319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY("I2S1", RT5645_PWR_DIG1,
21271319b2f6SOder Chiou RT5645_PWR_I2S1_BIT, 0, NULL, 0),
2128786aa09bSBard Liao SND_SOC_DAPM_PGA("IF1 DAC0", SND_SOC_NOPM, 0, 0, NULL, 0),
21291319b2f6SOder Chiou SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0),
21301319b2f6SOder Chiou SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0),
2131786aa09bSBard Liao SND_SOC_DAPM_PGA("IF1 DAC3", SND_SOC_NOPM, 0, 0, NULL, 0),
21321319b2f6SOder Chiou SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
21331319b2f6SOder Chiou SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0),
21341319b2f6SOder Chiou SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0),
21351319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY("I2S2", RT5645_PWR_DIG1,
21361319b2f6SOder Chiou RT5645_PWR_I2S2_BIT, 0, NULL, 0),
21371319b2f6SOder Chiou SND_SOC_DAPM_PGA("IF2 DAC", SND_SOC_NOPM, 0, 0, NULL, 0),
21381319b2f6SOder Chiou SND_SOC_DAPM_PGA("IF2 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0),
21391319b2f6SOder Chiou SND_SOC_DAPM_PGA("IF2 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0),
21401319b2f6SOder Chiou SND_SOC_DAPM_PGA("IF2 ADC", SND_SOC_NOPM, 0, 0, NULL, 0),
21411319b2f6SOder Chiou
21421319b2f6SOder Chiou /* Digital Interface Select */
21431319b2f6SOder Chiou SND_SOC_DAPM_MUX("VAD ADC Mux", SND_SOC_NOPM,
21441319b2f6SOder Chiou 0, 0, &rt5645_vad_adc_mux),
21451319b2f6SOder Chiou
21461319b2f6SOder Chiou /* Audio Interface */
21471319b2f6SOder Chiou SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
21481319b2f6SOder Chiou SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
21491319b2f6SOder Chiou SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
21501319b2f6SOder Chiou SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
21511319b2f6SOder Chiou
21521319b2f6SOder Chiou /* Output Side */
21531319b2f6SOder Chiou /* DAC mixer before sound effect */
21541319b2f6SOder Chiou SND_SOC_DAPM_MIXER("DAC1 MIXL", SND_SOC_NOPM, 0, 0,
21551319b2f6SOder Chiou rt5645_dac_l_mix, ARRAY_SIZE(rt5645_dac_l_mix)),
21561319b2f6SOder Chiou SND_SOC_DAPM_MIXER("DAC1 MIXR", SND_SOC_NOPM, 0, 0,
21571319b2f6SOder Chiou rt5645_dac_r_mix, ARRAY_SIZE(rt5645_dac_r_mix)),
21581319b2f6SOder Chiou
21591319b2f6SOder Chiou /* DAC2 channel Mux */
21601319b2f6SOder Chiou SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0, &rt5645_dac_l2_mux),
21611319b2f6SOder Chiou SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0, &rt5645_dac_r2_mux),
21621319b2f6SOder Chiou SND_SOC_DAPM_PGA("DAC L2 Volume", RT5645_PWR_DIG1,
21631319b2f6SOder Chiou RT5645_PWR_DAC_L2_BIT, 0, NULL, 0),
21641319b2f6SOder Chiou SND_SOC_DAPM_PGA("DAC R2 Volume", RT5645_PWR_DIG1,
21651319b2f6SOder Chiou RT5645_PWR_DAC_R2_BIT, 0, NULL, 0),
21661319b2f6SOder Chiou
21671319b2f6SOder Chiou SND_SOC_DAPM_MUX("DAC1 L Mux", SND_SOC_NOPM, 0, 0, &rt5645_dac1l_mux),
21681319b2f6SOder Chiou SND_SOC_DAPM_MUX("DAC1 R Mux", SND_SOC_NOPM, 0, 0, &rt5645_dac1r_mux),
21691319b2f6SOder Chiou
21701319b2f6SOder Chiou /* DAC Mixer */
21711319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY_S("dac stereo1 filter", 1, RT5645_PWR_DIG2,
21721319b2f6SOder Chiou RT5645_PWR_DAC_S1F_BIT, 0, NULL, 0),
21731319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY_S("dac mono left filter", 1, RT5645_PWR_DIG2,
21741319b2f6SOder Chiou RT5645_PWR_DAC_MF_L_BIT, 0, NULL, 0),
21751319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY_S("dac mono right filter", 1, RT5645_PWR_DIG2,
21761319b2f6SOder Chiou RT5645_PWR_DAC_MF_R_BIT, 0, NULL, 0),
21771319b2f6SOder Chiou SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0,
21781319b2f6SOder Chiou rt5645_sto_dac_l_mix, ARRAY_SIZE(rt5645_sto_dac_l_mix)),
21791319b2f6SOder Chiou SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0,
21801319b2f6SOder Chiou rt5645_sto_dac_r_mix, ARRAY_SIZE(rt5645_sto_dac_r_mix)),
21811319b2f6SOder Chiou SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0,
21821319b2f6SOder Chiou rt5645_mono_dac_l_mix, ARRAY_SIZE(rt5645_mono_dac_l_mix)),
21831319b2f6SOder Chiou SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0,
21841319b2f6SOder Chiou rt5645_mono_dac_r_mix, ARRAY_SIZE(rt5645_mono_dac_r_mix)),
21851319b2f6SOder Chiou SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0,
21861319b2f6SOder Chiou rt5645_dig_l_mix, ARRAY_SIZE(rt5645_dig_l_mix)),
21871319b2f6SOder Chiou SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0,
21881319b2f6SOder Chiou rt5645_dig_r_mix, ARRAY_SIZE(rt5645_dig_r_mix)),
21891319b2f6SOder Chiou
21901319b2f6SOder Chiou /* DACs */
21911319b2f6SOder Chiou SND_SOC_DAPM_DAC("DAC L1", NULL, RT5645_PWR_DIG1, RT5645_PWR_DAC_L1_BIT,
21921319b2f6SOder Chiou 0),
21931319b2f6SOder Chiou SND_SOC_DAPM_DAC("DAC L2", NULL, RT5645_PWR_DIG1, RT5645_PWR_DAC_L2_BIT,
21941319b2f6SOder Chiou 0),
21951319b2f6SOder Chiou SND_SOC_DAPM_DAC("DAC R1", NULL, RT5645_PWR_DIG1, RT5645_PWR_DAC_R1_BIT,
21961319b2f6SOder Chiou 0),
21971319b2f6SOder Chiou SND_SOC_DAPM_DAC("DAC R2", NULL, RT5645_PWR_DIG1, RT5645_PWR_DAC_R2_BIT,
21981319b2f6SOder Chiou 0),
21991319b2f6SOder Chiou /* OUT Mixer */
22001319b2f6SOder Chiou SND_SOC_DAPM_MIXER("SPK MIXL", RT5645_PWR_MIXER, RT5645_PWR_SM_L_BIT,
22011319b2f6SOder Chiou 0, rt5645_spk_l_mix, ARRAY_SIZE(rt5645_spk_l_mix)),
22021319b2f6SOder Chiou SND_SOC_DAPM_MIXER("SPK MIXR", RT5645_PWR_MIXER, RT5645_PWR_SM_R_BIT,
22031319b2f6SOder Chiou 0, rt5645_spk_r_mix, ARRAY_SIZE(rt5645_spk_r_mix)),
22041319b2f6SOder Chiou SND_SOC_DAPM_MIXER("OUT MIXL", RT5645_PWR_MIXER, RT5645_PWR_OM_L_BIT,
22051319b2f6SOder Chiou 0, rt5645_out_l_mix, ARRAY_SIZE(rt5645_out_l_mix)),
22061319b2f6SOder Chiou SND_SOC_DAPM_MIXER("OUT MIXR", RT5645_PWR_MIXER, RT5645_PWR_OM_R_BIT,
22071319b2f6SOder Chiou 0, rt5645_out_r_mix, ARRAY_SIZE(rt5645_out_r_mix)),
22081319b2f6SOder Chiou /* Ouput Volume */
22091319b2f6SOder Chiou SND_SOC_DAPM_SWITCH("SPKVOL L", RT5645_PWR_VOL, RT5645_PWR_SV_L_BIT, 0,
22101319b2f6SOder Chiou &spk_l_vol_control),
22111319b2f6SOder Chiou SND_SOC_DAPM_SWITCH("SPKVOL R", RT5645_PWR_VOL, RT5645_PWR_SV_R_BIT, 0,
22121319b2f6SOder Chiou &spk_r_vol_control),
22131319b2f6SOder Chiou SND_SOC_DAPM_MIXER("HPOVOL MIXL", RT5645_PWR_VOL, RT5645_PWR_HV_L_BIT,
22141319b2f6SOder Chiou 0, rt5645_hpvoll_mix, ARRAY_SIZE(rt5645_hpvoll_mix)),
22151319b2f6SOder Chiou SND_SOC_DAPM_MIXER("HPOVOL MIXR", RT5645_PWR_VOL, RT5645_PWR_HV_R_BIT,
22161319b2f6SOder Chiou 0, rt5645_hpvolr_mix, ARRAY_SIZE(rt5645_hpvolr_mix)),
22171319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY("HPOVOL MIXL Power", RT5645_PWR_MIXER,
22181319b2f6SOder Chiou RT5645_PWR_HM_L_BIT, 0, NULL, 0),
22191319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY("HPOVOL MIXR Power", RT5645_PWR_MIXER,
22201319b2f6SOder Chiou RT5645_PWR_HM_R_BIT, 0, NULL, 0),
22211319b2f6SOder Chiou SND_SOC_DAPM_PGA("DAC 1", SND_SOC_NOPM, 0, 0, NULL, 0),
22221319b2f6SOder Chiou SND_SOC_DAPM_PGA("DAC 2", SND_SOC_NOPM, 0, 0, NULL, 0),
22231319b2f6SOder Chiou SND_SOC_DAPM_PGA("HPOVOL", SND_SOC_NOPM, 0, 0, NULL, 0),
22241319b2f6SOder Chiou SND_SOC_DAPM_SWITCH("HPOVOL L", SND_SOC_NOPM, 0, 0, &hp_l_vol_control),
22251319b2f6SOder Chiou SND_SOC_DAPM_SWITCH("HPOVOL R", SND_SOC_NOPM, 0, 0, &hp_r_vol_control),
22261319b2f6SOder Chiou
22271319b2f6SOder Chiou /* HPO/LOUT/Mono Mixer */
22281319b2f6SOder Chiou SND_SOC_DAPM_MIXER("SPOL MIX", SND_SOC_NOPM, 0, 0, rt5645_spo_l_mix,
22291319b2f6SOder Chiou ARRAY_SIZE(rt5645_spo_l_mix)),
22301319b2f6SOder Chiou SND_SOC_DAPM_MIXER("SPOR MIX", SND_SOC_NOPM, 0, 0, rt5645_spo_r_mix,
22311319b2f6SOder Chiou ARRAY_SIZE(rt5645_spo_r_mix)),
22321319b2f6SOder Chiou SND_SOC_DAPM_MIXER("HPO MIX", SND_SOC_NOPM, 0, 0, rt5645_hpo_mix,
22331319b2f6SOder Chiou ARRAY_SIZE(rt5645_hpo_mix)),
22341319b2f6SOder Chiou SND_SOC_DAPM_MIXER("LOUT MIX", SND_SOC_NOPM, 0, 0, rt5645_lout_mix,
22351319b2f6SOder Chiou ARRAY_SIZE(rt5645_lout_mix)),
22361319b2f6SOder Chiou
22371319b2f6SOder Chiou SND_SOC_DAPM_PGA_S("HP amp", 1, SND_SOC_NOPM, 0, 0, rt5645_hp_event,
22381319b2f6SOder Chiou SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
22391319b2f6SOder Chiou SND_SOC_DAPM_PGA_S("LOUT amp", 1, SND_SOC_NOPM, 0, 0, rt5645_lout_event,
22401319b2f6SOder Chiou SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
22411319b2f6SOder Chiou SND_SOC_DAPM_PGA_S("SPK amp", 2, SND_SOC_NOPM, 0, 0, rt5645_spk_event,
22421319b2f6SOder Chiou SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
22431319b2f6SOder Chiou
22441319b2f6SOder Chiou /* PDM */
22451319b2f6SOder Chiou SND_SOC_DAPM_SUPPLY("PDM1 Power", RT5645_PWR_DIG2, RT5645_PWR_PDM1_BIT,
22461319b2f6SOder Chiou 0, NULL, 0),
22471319b2f6SOder Chiou SND_SOC_DAPM_MUX("PDM1 L Mux", SND_SOC_NOPM, 0, 0, &rt5645_pdm1_l_mux),
22481319b2f6SOder Chiou SND_SOC_DAPM_MUX("PDM1 R Mux", SND_SOC_NOPM, 0, 0, &rt5645_pdm1_r_mux),
22491319b2f6SOder Chiou
22501319b2f6SOder Chiou SND_SOC_DAPM_SWITCH("PDM1 L", SND_SOC_NOPM, 0, 0, &pdm1_l_vol_control),
22511319b2f6SOder Chiou SND_SOC_DAPM_SWITCH("PDM1 R", SND_SOC_NOPM, 0, 0, &pdm1_r_vol_control),
22521319b2f6SOder Chiou
22531319b2f6SOder Chiou /* Output Lines */
22541319b2f6SOder Chiou SND_SOC_DAPM_OUTPUT("HPOL"),
22551319b2f6SOder Chiou SND_SOC_DAPM_OUTPUT("HPOR"),
22561319b2f6SOder Chiou SND_SOC_DAPM_OUTPUT("LOUTL"),
22571319b2f6SOder Chiou SND_SOC_DAPM_OUTPUT("LOUTR"),
22581319b2f6SOder Chiou SND_SOC_DAPM_OUTPUT("PDM1L"),
22591319b2f6SOder Chiou SND_SOC_DAPM_OUTPUT("PDM1R"),
22601319b2f6SOder Chiou SND_SOC_DAPM_OUTPUT("SPOL"),
22611319b2f6SOder Chiou SND_SOC_DAPM_OUTPUT("SPOR"),
22621319b2f6SOder Chiou };
22631319b2f6SOder Chiou
226483c09290SBard Liao static const struct snd_soc_dapm_widget rt5645_specific_dapm_widgets[] = {
226583c09290SBard Liao SND_SOC_DAPM_MUX("RT5645 IF1 DAC1 L Mux", SND_SOC_NOPM, 0, 0,
226683c09290SBard Liao &rt5645_if1_dac0_tdm_sel_mux),
226783c09290SBard Liao SND_SOC_DAPM_MUX("RT5645 IF1 DAC1 R Mux", SND_SOC_NOPM, 0, 0,
226883c09290SBard Liao &rt5645_if1_dac1_tdm_sel_mux),
226983c09290SBard Liao SND_SOC_DAPM_MUX("RT5645 IF1 DAC2 L Mux", SND_SOC_NOPM, 0, 0,
227083c09290SBard Liao &rt5645_if1_dac2_tdm_sel_mux),
227183c09290SBard Liao SND_SOC_DAPM_MUX("RT5645 IF1 DAC2 R Mux", SND_SOC_NOPM, 0, 0,
227283c09290SBard Liao &rt5645_if1_dac3_tdm_sel_mux),
227383c09290SBard Liao SND_SOC_DAPM_MUX("RT5645 IF1 ADC Mux", SND_SOC_NOPM,
227483c09290SBard Liao 0, 0, &rt5645_if1_adc_in_mux),
227583c09290SBard Liao SND_SOC_DAPM_MUX("RT5645 IF1 ADC1 Swap Mux", SND_SOC_NOPM,
227683c09290SBard Liao 0, 0, &rt5645_if1_adc1_in_mux),
227783c09290SBard Liao SND_SOC_DAPM_MUX("RT5645 IF1 ADC2 Swap Mux", SND_SOC_NOPM,
227883c09290SBard Liao 0, 0, &rt5645_if1_adc2_in_mux),
227983c09290SBard Liao SND_SOC_DAPM_MUX("RT5645 IF1 ADC3 Swap Mux", SND_SOC_NOPM,
228083c09290SBard Liao 0, 0, &rt5645_if1_adc3_in_mux),
22811319b2f6SOder Chiou };
22821319b2f6SOder Chiou
22835c4ca99dSBard Liao static const struct snd_soc_dapm_widget rt5650_specific_dapm_widgets[] = {
22845c4ca99dSBard Liao SND_SOC_DAPM_MUX("A DAC1 L Mux", SND_SOC_NOPM,
22855c4ca99dSBard Liao 0, 0, &rt5650_a_dac1_l_mux),
22865c4ca99dSBard Liao SND_SOC_DAPM_MUX("A DAC1 R Mux", SND_SOC_NOPM,
22875c4ca99dSBard Liao 0, 0, &rt5650_a_dac1_r_mux),
22885c4ca99dSBard Liao SND_SOC_DAPM_MUX("A DAC2 L Mux", SND_SOC_NOPM,
22895c4ca99dSBard Liao 0, 0, &rt5650_a_dac2_l_mux),
22905c4ca99dSBard Liao SND_SOC_DAPM_MUX("A DAC2 R Mux", SND_SOC_NOPM,
22915c4ca99dSBard Liao 0, 0, &rt5650_a_dac2_r_mux),
2292851b81e8SMichele Curti
2293851b81e8SMichele Curti SND_SOC_DAPM_MUX("RT5650 IF1 ADC1 Swap Mux", SND_SOC_NOPM,
2294851b81e8SMichele Curti 0, 0, &rt5650_if1_adc1_in_mux),
2295851b81e8SMichele Curti SND_SOC_DAPM_MUX("RT5650 IF1 ADC2 Swap Mux", SND_SOC_NOPM,
2296851b81e8SMichele Curti 0, 0, &rt5650_if1_adc2_in_mux),
2297851b81e8SMichele Curti SND_SOC_DAPM_MUX("RT5650 IF1 ADC3 Swap Mux", SND_SOC_NOPM,
2298851b81e8SMichele Curti 0, 0, &rt5650_if1_adc3_in_mux),
2299851b81e8SMichele Curti SND_SOC_DAPM_MUX("RT5650 IF1 ADC Mux", SND_SOC_NOPM,
2300851b81e8SMichele Curti 0, 0, &rt5650_if1_adc_in_mux),
2301851b81e8SMichele Curti
2302851b81e8SMichele Curti SND_SOC_DAPM_MUX("RT5650 IF1 DAC1 L Mux", SND_SOC_NOPM, 0, 0,
2303851b81e8SMichele Curti &rt5650_if1_dac0_tdm_sel_mux),
2304851b81e8SMichele Curti SND_SOC_DAPM_MUX("RT5650 IF1 DAC1 R Mux", SND_SOC_NOPM, 0, 0,
2305851b81e8SMichele Curti &rt5650_if1_dac1_tdm_sel_mux),
2306851b81e8SMichele Curti SND_SOC_DAPM_MUX("RT5650 IF1 DAC2 L Mux", SND_SOC_NOPM, 0, 0,
2307851b81e8SMichele Curti &rt5650_if1_dac2_tdm_sel_mux),
2308851b81e8SMichele Curti SND_SOC_DAPM_MUX("RT5650 IF1 DAC2 R Mux", SND_SOC_NOPM, 0, 0,
2309851b81e8SMichele Curti &rt5650_if1_dac3_tdm_sel_mux),
23105c4ca99dSBard Liao };
23115c4ca99dSBard Liao
23121319b2f6SOder Chiou static const struct snd_soc_dapm_route rt5645_dapm_routes[] = {
23139e268353SBard Liao { "adc stereo1 filter", NULL, "ADC STO1 ASRC", is_using_asrc },
23149e268353SBard Liao { "adc mono left filter", NULL, "ADC MONO L ASRC", is_using_asrc },
23159e268353SBard Liao { "adc mono right filter", NULL, "ADC MONO R ASRC", is_using_asrc },
23169e268353SBard Liao { "dac mono left filter", NULL, "DAC MONO L ASRC", is_using_asrc },
23179e268353SBard Liao { "dac mono right filter", NULL, "DAC MONO R ASRC", is_using_asrc },
23189e268353SBard Liao { "dac stereo1 filter", NULL, "DAC STO ASRC", is_using_asrc },
23199e268353SBard Liao
23209e268353SBard Liao { "I2S1", NULL, "I2S1 ASRC" },
23219e268353SBard Liao { "I2S2", NULL, "I2S2 ASRC" },
23229e268353SBard Liao
23231319b2f6SOder Chiou { "IN1P", NULL, "LDO2" },
23241319b2f6SOder Chiou { "IN2P", NULL, "LDO2" },
23251319b2f6SOder Chiou
23261319b2f6SOder Chiou { "DMIC1", NULL, "DMIC L1" },
23271319b2f6SOder Chiou { "DMIC1", NULL, "DMIC R1" },
23281319b2f6SOder Chiou { "DMIC2", NULL, "DMIC L2" },
23291319b2f6SOder Chiou { "DMIC2", NULL, "DMIC R2" },
23301319b2f6SOder Chiou
23311319b2f6SOder Chiou { "BST1", NULL, "IN1P" },
23321319b2f6SOder Chiou { "BST1", NULL, "IN1N" },
23331319b2f6SOder Chiou { "BST1", NULL, "JD Power" },
23341319b2f6SOder Chiou { "BST1", NULL, "Mic Det Power" },
23351319b2f6SOder Chiou { "BST2", NULL, "IN2P" },
23361319b2f6SOder Chiou { "BST2", NULL, "IN2N" },
23371319b2f6SOder Chiou
23381319b2f6SOder Chiou { "INL VOL", NULL, "IN2P" },
23391319b2f6SOder Chiou { "INR VOL", NULL, "IN2N" },
23401319b2f6SOder Chiou
23411319b2f6SOder Chiou { "RECMIXL", "HPOL Switch", "HPOL" },
23421319b2f6SOder Chiou { "RECMIXL", "INL Switch", "INL VOL" },
23431319b2f6SOder Chiou { "RECMIXL", "BST2 Switch", "BST2" },
23441319b2f6SOder Chiou { "RECMIXL", "BST1 Switch", "BST1" },
23451319b2f6SOder Chiou { "RECMIXL", "OUT MIXL Switch", "OUT MIXL" },
23461319b2f6SOder Chiou
23471319b2f6SOder Chiou { "RECMIXR", "HPOR Switch", "HPOR" },
23481319b2f6SOder Chiou { "RECMIXR", "INR Switch", "INR VOL" },
23491319b2f6SOder Chiou { "RECMIXR", "BST2 Switch", "BST2" },
23501319b2f6SOder Chiou { "RECMIXR", "BST1 Switch", "BST1" },
23511319b2f6SOder Chiou { "RECMIXR", "OUT MIXR Switch", "OUT MIXR" },
23521319b2f6SOder Chiou
23531319b2f6SOder Chiou { "ADC L", NULL, "RECMIXL" },
23541319b2f6SOder Chiou { "ADC L", NULL, "ADC L power" },
23551319b2f6SOder Chiou { "ADC R", NULL, "RECMIXR" },
23561319b2f6SOder Chiou { "ADC R", NULL, "ADC R power" },
23571319b2f6SOder Chiou
23581319b2f6SOder Chiou {"DMIC L1", NULL, "DMIC CLK"},
23591319b2f6SOder Chiou {"DMIC L1", NULL, "DMIC1 Power"},
23601319b2f6SOder Chiou {"DMIC R1", NULL, "DMIC CLK"},
23611319b2f6SOder Chiou {"DMIC R1", NULL, "DMIC1 Power"},
23621319b2f6SOder Chiou {"DMIC L2", NULL, "DMIC CLK"},
23631319b2f6SOder Chiou {"DMIC L2", NULL, "DMIC2 Power"},
23641319b2f6SOder Chiou {"DMIC R2", NULL, "DMIC CLK"},
23651319b2f6SOder Chiou {"DMIC R2", NULL, "DMIC2 Power"},
23661319b2f6SOder Chiou
23671319b2f6SOder Chiou { "Stereo1 DMIC Mux", "DMIC1", "DMIC1" },
23681319b2f6SOder Chiou { "Stereo1 DMIC Mux", "DMIC2", "DMIC2" },
23699e268353SBard Liao { "Stereo1 DMIC Mux", NULL, "DMIC STO1 ASRC" },
23701319b2f6SOder Chiou
23711319b2f6SOder Chiou { "Mono DMIC L Mux", "DMIC1", "DMIC L1" },
23721319b2f6SOder Chiou { "Mono DMIC L Mux", "DMIC2", "DMIC L2" },
23739e268353SBard Liao { "Mono DMIC L Mux", NULL, "DMIC MONO L ASRC" },
23741319b2f6SOder Chiou
23751319b2f6SOder Chiou { "Mono DMIC R Mux", "DMIC1", "DMIC R1" },
23761319b2f6SOder Chiou { "Mono DMIC R Mux", "DMIC2", "DMIC R2" },
23779e268353SBard Liao { "Mono DMIC R Mux", NULL, "DMIC MONO R ASRC" },
23781319b2f6SOder Chiou
23791319b2f6SOder Chiou { "Stereo1 ADC L2 Mux", "DMIC", "Stereo1 DMIC Mux" },
23801319b2f6SOder Chiou { "Stereo1 ADC L2 Mux", "DAC MIX", "DAC MIXL" },
23811319b2f6SOder Chiou { "Stereo1 ADC L1 Mux", "ADC", "ADC L" },
23821319b2f6SOder Chiou { "Stereo1 ADC L1 Mux", "DAC MIX", "DAC MIXL" },
23831319b2f6SOder Chiou
23841319b2f6SOder Chiou { "Stereo1 ADC R1 Mux", "ADC", "ADC R" },
23851319b2f6SOder Chiou { "Stereo1 ADC R1 Mux", "DAC MIX", "DAC MIXR" },
23861319b2f6SOder Chiou { "Stereo1 ADC R2 Mux", "DMIC", "Stereo1 DMIC Mux" },
23871319b2f6SOder Chiou { "Stereo1 ADC R2 Mux", "DAC MIX", "DAC MIXR" },
23881319b2f6SOder Chiou
23891319b2f6SOder Chiou { "Mono ADC L2 Mux", "DMIC", "Mono DMIC L Mux" },
23901319b2f6SOder Chiou { "Mono ADC L2 Mux", "Mono DAC MIXL", "Mono DAC MIXL" },
23911319b2f6SOder Chiou { "Mono ADC L1 Mux", "Mono DAC MIXL", "Mono DAC MIXL" },
23921319b2f6SOder Chiou { "Mono ADC L1 Mux", "ADC", "ADC L" },
23931319b2f6SOder Chiou
23941319b2f6SOder Chiou { "Mono ADC R1 Mux", "Mono DAC MIXR", "Mono DAC MIXR" },
23951319b2f6SOder Chiou { "Mono ADC R1 Mux", "ADC", "ADC R" },
23961319b2f6SOder Chiou { "Mono ADC R2 Mux", "DMIC", "Mono DMIC R Mux" },
23971319b2f6SOder Chiou { "Mono ADC R2 Mux", "Mono DAC MIXR", "Mono DAC MIXR" },
23981319b2f6SOder Chiou
23991319b2f6SOder Chiou { "Sto1 ADC MIXL", "ADC1 Switch", "Stereo1 ADC L1 Mux" },
24001319b2f6SOder Chiou { "Sto1 ADC MIXL", "ADC2 Switch", "Stereo1 ADC L2 Mux" },
24011319b2f6SOder Chiou { "Sto1 ADC MIXR", "ADC1 Switch", "Stereo1 ADC R1 Mux" },
24021319b2f6SOder Chiou { "Sto1 ADC MIXR", "ADC2 Switch", "Stereo1 ADC R2 Mux" },
24031319b2f6SOder Chiou
24041319b2f6SOder Chiou { "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" },
24051319b2f6SOder Chiou { "Stereo1 ADC MIXL", NULL, "adc stereo1 filter" },
24061319b2f6SOder Chiou { "adc stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll },
24071319b2f6SOder Chiou
24081319b2f6SOder Chiou { "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" },
24091319b2f6SOder Chiou { "Stereo1 ADC MIXR", NULL, "adc stereo1 filter" },
24101319b2f6SOder Chiou { "adc stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll },
24111319b2f6SOder Chiou
24121319b2f6SOder Chiou { "Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux" },
24131319b2f6SOder Chiou { "Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux" },
24141319b2f6SOder Chiou { "Mono ADC MIXL", NULL, "adc mono left filter" },
24151319b2f6SOder Chiou { "adc mono left filter", NULL, "PLL1", is_sys_clk_from_pll },
24161319b2f6SOder Chiou
24171319b2f6SOder Chiou { "Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux" },
24181319b2f6SOder Chiou { "Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux" },
24191319b2f6SOder Chiou { "Mono ADC MIXR", NULL, "adc mono right filter" },
24201319b2f6SOder Chiou { "adc mono right filter", NULL, "PLL1", is_sys_clk_from_pll },
24211319b2f6SOder Chiou
24221319b2f6SOder Chiou { "VAD ADC Mux", "Sto1 ADC L", "Stereo1 ADC MIXL" },
24231319b2f6SOder Chiou { "VAD ADC Mux", "Mono ADC L", "Mono ADC MIXL" },
24241319b2f6SOder Chiou { "VAD ADC Mux", "Mono ADC R", "Mono ADC MIXR" },
24251319b2f6SOder Chiou
24261319b2f6SOder Chiou { "IF_ADC1", NULL, "Stereo1 ADC MIXL" },
24271319b2f6SOder Chiou { "IF_ADC1", NULL, "Stereo1 ADC MIXR" },
24281319b2f6SOder Chiou { "IF_ADC2", NULL, "Mono ADC MIXL" },
24291319b2f6SOder Chiou { "IF_ADC2", NULL, "Mono ADC MIXR" },
24301319b2f6SOder Chiou { "VAD_ADC", NULL, "VAD ADC Mux" },
24311319b2f6SOder Chiou
24321319b2f6SOder Chiou { "IF2 ADC Mux", "IF_ADC1", "IF_ADC1" },
24331319b2f6SOder Chiou { "IF2 ADC Mux", "IF_ADC2", "IF_ADC2" },
24341319b2f6SOder Chiou { "IF2 ADC Mux", "VAD_ADC", "VAD_ADC" },
24351319b2f6SOder Chiou
24361319b2f6SOder Chiou { "IF1 ADC", NULL, "I2S1" },
24371319b2f6SOder Chiou { "IF2 ADC", NULL, "I2S2" },
24381319b2f6SOder Chiou { "IF2 ADC", NULL, "IF2 ADC Mux" },
24391319b2f6SOder Chiou
24401319b2f6SOder Chiou { "AIF2TX", NULL, "IF2 ADC" },
24411319b2f6SOder Chiou
244221ab3f2bSBard Liao { "IF1 DAC0", NULL, "AIF1RX" },
24431319b2f6SOder Chiou { "IF1 DAC1", NULL, "AIF1RX" },
24441319b2f6SOder Chiou { "IF1 DAC2", NULL, "AIF1RX" },
244521ab3f2bSBard Liao { "IF1 DAC3", NULL, "AIF1RX" },
24461319b2f6SOder Chiou { "IF2 DAC", NULL, "AIF2RX" },
24471319b2f6SOder Chiou
244821ab3f2bSBard Liao { "IF1 DAC0", NULL, "I2S1" },
24491319b2f6SOder Chiou { "IF1 DAC1", NULL, "I2S1" },
24501319b2f6SOder Chiou { "IF1 DAC2", NULL, "I2S1" },
245121ab3f2bSBard Liao { "IF1 DAC3", NULL, "I2S1" },
24521319b2f6SOder Chiou { "IF2 DAC", NULL, "I2S2" },
24531319b2f6SOder Chiou
24541319b2f6SOder Chiou { "IF2 DAC L", NULL, "IF2 DAC" },
24551319b2f6SOder Chiou { "IF2 DAC R", NULL, "IF2 DAC" },
24561319b2f6SOder Chiou
24571319b2f6SOder Chiou { "DAC1 L Mux", "IF2 DAC", "IF2 DAC L" },
24581319b2f6SOder Chiou { "DAC1 R Mux", "IF2 DAC", "IF2 DAC R" },
24591319b2f6SOder Chiou
24601319b2f6SOder Chiou { "DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL" },
24611319b2f6SOder Chiou { "DAC1 MIXL", "DAC1 Switch", "DAC1 L Mux" },
24621319b2f6SOder Chiou { "DAC1 MIXL", NULL, "dac stereo1 filter" },
24631319b2f6SOder Chiou { "DAC1 MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR" },
24641319b2f6SOder Chiou { "DAC1 MIXR", "DAC1 Switch", "DAC1 R Mux" },
24651319b2f6SOder Chiou { "DAC1 MIXR", NULL, "dac stereo1 filter" },
24661319b2f6SOder Chiou
24671319b2f6SOder Chiou { "DAC L2 Mux", "IF2 DAC", "IF2 DAC L" },
24681319b2f6SOder Chiou { "DAC L2 Mux", "Mono ADC", "Mono ADC MIXL" },
24691319b2f6SOder Chiou { "DAC L2 Mux", "VAD_ADC", "VAD_ADC" },
24701319b2f6SOder Chiou { "DAC L2 Volume", NULL, "DAC L2 Mux" },
24711319b2f6SOder Chiou { "DAC L2 Volume", NULL, "dac mono left filter" },
24721319b2f6SOder Chiou
24731319b2f6SOder Chiou { "DAC R2 Mux", "IF2 DAC", "IF2 DAC R" },
24741319b2f6SOder Chiou { "DAC R2 Mux", "Mono ADC", "Mono ADC MIXR" },
24751319b2f6SOder Chiou { "DAC R2 Mux", "Haptic", "Haptic Generator" },
24761319b2f6SOder Chiou { "DAC R2 Volume", NULL, "DAC R2 Mux" },
24771319b2f6SOder Chiou { "DAC R2 Volume", NULL, "dac mono right filter" },
24781319b2f6SOder Chiou
24791319b2f6SOder Chiou { "Stereo DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
24801319b2f6SOder Chiou { "Stereo DAC MIXL", "DAC R1 Switch", "DAC1 MIXR" },
24811319b2f6SOder Chiou { "Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
24821319b2f6SOder Chiou { "Stereo DAC MIXL", NULL, "dac stereo1 filter" },
24831319b2f6SOder Chiou { "Stereo DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" },
24841319b2f6SOder Chiou { "Stereo DAC MIXR", "DAC L1 Switch", "DAC1 MIXL" },
24851319b2f6SOder Chiou { "Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
24861319b2f6SOder Chiou { "Stereo DAC MIXR", NULL, "dac stereo1 filter" },
24871319b2f6SOder Chiou
24881319b2f6SOder Chiou { "Mono DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
24891319b2f6SOder Chiou { "Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
24901319b2f6SOder Chiou { "Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Volume" },
24911319b2f6SOder Chiou { "Mono DAC MIXL", NULL, "dac mono left filter" },
24921319b2f6SOder Chiou { "Mono DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" },
24931319b2f6SOder Chiou { "Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
24941319b2f6SOder Chiou { "Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" },
24951319b2f6SOder Chiou { "Mono DAC MIXR", NULL, "dac mono right filter" },
24961319b2f6SOder Chiou
24971319b2f6SOder Chiou { "DAC MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" },
24981319b2f6SOder Chiou { "DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
24991319b2f6SOder Chiou { "DAC MIXL", "DAC R2 Switch", "DAC R2 Volume" },
25001319b2f6SOder Chiou { "DAC MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" },
25011319b2f6SOder Chiou { "DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" },
25021319b2f6SOder Chiou { "DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" },
25031319b2f6SOder Chiou
25041319b2f6SOder Chiou { "DAC L1", NULL, "PLL1", is_sys_clk_from_pll },
25051319b2f6SOder Chiou { "DAC R1", NULL, "PLL1", is_sys_clk_from_pll },
25061319b2f6SOder Chiou { "DAC L2", NULL, "PLL1", is_sys_clk_from_pll },
25071319b2f6SOder Chiou { "DAC R2", NULL, "PLL1", is_sys_clk_from_pll },
25081319b2f6SOder Chiou
25091319b2f6SOder Chiou { "SPK MIXL", "BST1 Switch", "BST1" },
25101319b2f6SOder Chiou { "SPK MIXL", "INL Switch", "INL VOL" },
25111319b2f6SOder Chiou { "SPK MIXL", "DAC L1 Switch", "DAC L1" },
25121319b2f6SOder Chiou { "SPK MIXL", "DAC L2 Switch", "DAC L2" },
25131319b2f6SOder Chiou { "SPK MIXR", "BST2 Switch", "BST2" },
25141319b2f6SOder Chiou { "SPK MIXR", "INR Switch", "INR VOL" },
25151319b2f6SOder Chiou { "SPK MIXR", "DAC R1 Switch", "DAC R1" },
25161319b2f6SOder Chiou { "SPK MIXR", "DAC R2 Switch", "DAC R2" },
25171319b2f6SOder Chiou
25181319b2f6SOder Chiou { "OUT MIXL", "BST1 Switch", "BST1" },
25191319b2f6SOder Chiou { "OUT MIXL", "INL Switch", "INL VOL" },
25201319b2f6SOder Chiou { "OUT MIXL", "DAC L2 Switch", "DAC L2" },
25211319b2f6SOder Chiou { "OUT MIXL", "DAC L1 Switch", "DAC L1" },
25221319b2f6SOder Chiou
25231319b2f6SOder Chiou { "OUT MIXR", "BST2 Switch", "BST2" },
25241319b2f6SOder Chiou { "OUT MIXR", "INR Switch", "INR VOL" },
25251319b2f6SOder Chiou { "OUT MIXR", "DAC R2 Switch", "DAC R2" },
25261319b2f6SOder Chiou { "OUT MIXR", "DAC R1 Switch", "DAC R1" },
25271319b2f6SOder Chiou
25281319b2f6SOder Chiou { "HPOVOL MIXL", "DAC1 Switch", "DAC L1" },
25291319b2f6SOder Chiou { "HPOVOL MIXL", "DAC2 Switch", "DAC L2" },
25301319b2f6SOder Chiou { "HPOVOL MIXL", "INL Switch", "INL VOL" },
25311319b2f6SOder Chiou { "HPOVOL MIXL", "BST1 Switch", "BST1" },
25321319b2f6SOder Chiou { "HPOVOL MIXL", NULL, "HPOVOL MIXL Power" },
25331319b2f6SOder Chiou { "HPOVOL MIXR", "DAC1 Switch", "DAC R1" },
25341319b2f6SOder Chiou { "HPOVOL MIXR", "DAC2 Switch", "DAC R2" },
25351319b2f6SOder Chiou { "HPOVOL MIXR", "INR Switch", "INR VOL" },
25361319b2f6SOder Chiou { "HPOVOL MIXR", "BST2 Switch", "BST2" },
25371319b2f6SOder Chiou { "HPOVOL MIXR", NULL, "HPOVOL MIXR Power" },
25381319b2f6SOder Chiou
25391319b2f6SOder Chiou { "DAC 2", NULL, "DAC L2" },
25401319b2f6SOder Chiou { "DAC 2", NULL, "DAC R2" },
25411319b2f6SOder Chiou { "DAC 1", NULL, "DAC L1" },
25421319b2f6SOder Chiou { "DAC 1", NULL, "DAC R1" },
25431319b2f6SOder Chiou { "HPOVOL L", "Switch", "HPOVOL MIXL" },
25441319b2f6SOder Chiou { "HPOVOL R", "Switch", "HPOVOL MIXR" },
25451319b2f6SOder Chiou { "HPOVOL", NULL, "HPOVOL L" },
25461319b2f6SOder Chiou { "HPOVOL", NULL, "HPOVOL R" },
25471319b2f6SOder Chiou { "HPO MIX", "DAC1 Switch", "DAC 1" },
25481319b2f6SOder Chiou { "HPO MIX", "HPVOL Switch", "HPOVOL" },
25491319b2f6SOder Chiou
25501319b2f6SOder Chiou { "SPKVOL L", "Switch", "SPK MIXL" },
25511319b2f6SOder Chiou { "SPKVOL R", "Switch", "SPK MIXR" },
25521319b2f6SOder Chiou
25531319b2f6SOder Chiou { "SPOL MIX", "DAC L1 Switch", "DAC L1" },
25541319b2f6SOder Chiou { "SPOL MIX", "SPKVOL L Switch", "SPKVOL L" },
25551319b2f6SOder Chiou { "SPOR MIX", "DAC R1 Switch", "DAC R1" },
25561319b2f6SOder Chiou { "SPOR MIX", "SPKVOL R Switch", "SPKVOL R" },
25571319b2f6SOder Chiou
25581319b2f6SOder Chiou { "LOUT MIX", "DAC L1 Switch", "DAC L1" },
25591319b2f6SOder Chiou { "LOUT MIX", "DAC R1 Switch", "DAC R1" },
25601319b2f6SOder Chiou { "LOUT MIX", "OUTMIX L Switch", "OUT MIXL" },
25611319b2f6SOder Chiou { "LOUT MIX", "OUTMIX R Switch", "OUT MIXR" },
25621319b2f6SOder Chiou
25631319b2f6SOder Chiou { "PDM1 L Mux", "Stereo DAC", "Stereo DAC MIXL" },
25641319b2f6SOder Chiou { "PDM1 L Mux", "Mono DAC", "Mono DAC MIXL" },
25651319b2f6SOder Chiou { "PDM1 L Mux", NULL, "PDM1 Power" },
25661319b2f6SOder Chiou { "PDM1 R Mux", "Stereo DAC", "Stereo DAC MIXR" },
25671319b2f6SOder Chiou { "PDM1 R Mux", "Mono DAC", "Mono DAC MIXR" },
25681319b2f6SOder Chiou { "PDM1 R Mux", NULL, "PDM1 Power" },
25691319b2f6SOder Chiou
25701319b2f6SOder Chiou { "HP amp", NULL, "HPO MIX" },
25711319b2f6SOder Chiou { "HP amp", NULL, "JD Power" },
25721319b2f6SOder Chiou { "HP amp", NULL, "Mic Det Power" },
25731319b2f6SOder Chiou { "HP amp", NULL, "LDO2" },
25741319b2f6SOder Chiou { "HPOL", NULL, "HP amp" },
25751319b2f6SOder Chiou { "HPOR", NULL, "HP amp" },
25761319b2f6SOder Chiou
25771319b2f6SOder Chiou { "LOUT amp", NULL, "LOUT MIX" },
25781319b2f6SOder Chiou { "LOUTL", NULL, "LOUT amp" },
25791319b2f6SOder Chiou { "LOUTR", NULL, "LOUT amp" },
25801319b2f6SOder Chiou
25811319b2f6SOder Chiou { "PDM1 L", "Switch", "PDM1 L Mux" },
25821319b2f6SOder Chiou { "PDM1 R", "Switch", "PDM1 R Mux" },
25831319b2f6SOder Chiou
25841319b2f6SOder Chiou { "PDM1L", NULL, "PDM1 L" },
25851319b2f6SOder Chiou { "PDM1R", NULL, "PDM1 R" },
25861319b2f6SOder Chiou
25871319b2f6SOder Chiou { "SPK amp", NULL, "SPOL MIX" },
25881319b2f6SOder Chiou { "SPK amp", NULL, "SPOR MIX" },
25891319b2f6SOder Chiou { "SPOL", NULL, "SPK amp" },
25901319b2f6SOder Chiou { "SPOR", NULL, "SPK amp" },
25911319b2f6SOder Chiou };
25921319b2f6SOder Chiou
25935c4ca99dSBard Liao static const struct snd_soc_dapm_route rt5650_specific_dapm_routes[] = {
25945c4ca99dSBard Liao { "A DAC1 L Mux", "DAC1", "DAC1 MIXL"},
25955c4ca99dSBard Liao { "A DAC1 L Mux", "Stereo DAC Mixer", "Stereo DAC MIXL"},
25965c4ca99dSBard Liao { "A DAC1 R Mux", "DAC1", "DAC1 MIXR"},
25975c4ca99dSBard Liao { "A DAC1 R Mux", "Stereo DAC Mixer", "Stereo DAC MIXR"},
25985c4ca99dSBard Liao
25995c4ca99dSBard Liao { "A DAC2 L Mux", "Stereo DAC Mixer", "Stereo DAC MIXL"},
26005c4ca99dSBard Liao { "A DAC2 L Mux", "Mono DAC Mixer", "Mono DAC MIXL"},
26015c4ca99dSBard Liao { "A DAC2 R Mux", "Stereo DAC Mixer", "Stereo DAC MIXR"},
26025c4ca99dSBard Liao { "A DAC2 R Mux", "Mono DAC Mixer", "Mono DAC MIXR"},
26035c4ca99dSBard Liao
26045c4ca99dSBard Liao { "DAC L1", NULL, "A DAC1 L Mux" },
26055c4ca99dSBard Liao { "DAC R1", NULL, "A DAC1 R Mux" },
26065c4ca99dSBard Liao { "DAC L2", NULL, "A DAC2 L Mux" },
26075c4ca99dSBard Liao { "DAC R2", NULL, "A DAC2 R Mux" },
260821ab3f2bSBard Liao
260921ab3f2bSBard Liao { "RT5650 IF1 ADC1 Swap Mux", "L/R", "IF_ADC1" },
261021ab3f2bSBard Liao { "RT5650 IF1 ADC1 Swap Mux", "R/L", "IF_ADC1" },
261121ab3f2bSBard Liao { "RT5650 IF1 ADC1 Swap Mux", "L/L", "IF_ADC1" },
261221ab3f2bSBard Liao { "RT5650 IF1 ADC1 Swap Mux", "R/R", "IF_ADC1" },
261321ab3f2bSBard Liao
261421ab3f2bSBard Liao { "RT5650 IF1 ADC2 Swap Mux", "L/R", "IF_ADC2" },
261521ab3f2bSBard Liao { "RT5650 IF1 ADC2 Swap Mux", "R/L", "IF_ADC2" },
261621ab3f2bSBard Liao { "RT5650 IF1 ADC2 Swap Mux", "L/L", "IF_ADC2" },
261721ab3f2bSBard Liao { "RT5650 IF1 ADC2 Swap Mux", "R/R", "IF_ADC2" },
261821ab3f2bSBard Liao
261921ab3f2bSBard Liao { "RT5650 IF1 ADC3 Swap Mux", "L/R", "VAD_ADC" },
262021ab3f2bSBard Liao { "RT5650 IF1 ADC3 Swap Mux", "R/L", "VAD_ADC" },
262121ab3f2bSBard Liao { "RT5650 IF1 ADC3 Swap Mux", "L/L", "VAD_ADC" },
262221ab3f2bSBard Liao { "RT5650 IF1 ADC3 Swap Mux", "R/R", "VAD_ADC" },
262321ab3f2bSBard Liao
262421ab3f2bSBard Liao { "IF1 ADC", NULL, "RT5650 IF1 ADC1 Swap Mux" },
262521ab3f2bSBard Liao { "IF1 ADC", NULL, "RT5650 IF1 ADC2 Swap Mux" },
262621ab3f2bSBard Liao { "IF1 ADC", NULL, "RT5650 IF1 ADC3 Swap Mux" },
262721ab3f2bSBard Liao
262821ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "IF_ADC1/IF_ADC2/DAC_REF/Null", "IF1 ADC" },
262921ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "IF_ADC1/IF_ADC2/Null/DAC_REF", "IF1 ADC" },
263021ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "IF_ADC1/DAC_REF/IF_ADC2/Null", "IF1 ADC" },
263121ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "IF_ADC1/DAC_REF/Null/IF_ADC2", "IF1 ADC" },
263221ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "IF_ADC1/Null/DAC_REF/IF_ADC2", "IF1 ADC" },
263321ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "IF_ADC1/Null/IF_ADC2/DAC_REF", "IF1 ADC" },
263421ab3f2bSBard Liao
263521ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "IF_ADC2/IF_ADC1/DAC_REF/Null", "IF1 ADC" },
263621ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "IF_ADC2/IF_ADC1/Null/DAC_REF", "IF1 ADC" },
263721ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "IF_ADC2/DAC_REF/IF_ADC1/Null", "IF1 ADC" },
263821ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "IF_ADC2/DAC_REF/Null/IF_ADC1", "IF1 ADC" },
263921ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "IF_ADC2/Null/DAC_REF/IF_ADC1", "IF1 ADC" },
264021ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "IF_ADC2/Null/IF_ADC1/DAC_REF", "IF1 ADC" },
264121ab3f2bSBard Liao
264221ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "DAC_REF/IF_ADC1/IF_ADC2/Null", "IF1 ADC" },
264321ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "DAC_REF/IF_ADC1/Null/IF_ADC2", "IF1 ADC" },
264421ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "DAC_REF/IF_ADC2/IF_ADC1/Null", "IF1 ADC" },
264521ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "DAC_REF/IF_ADC2/Null/IF_ADC1", "IF1 ADC" },
264621ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "DAC_REF/Null/IF_ADC1/IF_ADC2", "IF1 ADC" },
264721ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "DAC_REF/Null/IF_ADC2/IF_ADC1", "IF1 ADC" },
264821ab3f2bSBard Liao
264921ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "Null/IF_ADC1/IF_ADC2/DAC_REF", "IF1 ADC" },
265021ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "Null/IF_ADC1/DAC_REF/IF_ADC2", "IF1 ADC" },
265121ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "Null/IF_ADC2/IF_ADC1/DAC_REF", "IF1 ADC" },
265221ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "Null/IF_ADC2/DAC_REF/IF_ADC1", "IF1 ADC" },
265321ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "Null/DAC_REF/IF_ADC1/IF_ADC2", "IF1 ADC" },
265421ab3f2bSBard Liao { "RT5650 IF1 ADC Mux", "Null/DAC_REF/IF_ADC2/IF_ADC1", "IF1 ADC" },
265521ab3f2bSBard Liao { "AIF1TX", NULL, "RT5650 IF1 ADC Mux" },
265621ab3f2bSBard Liao
265721ab3f2bSBard Liao { "RT5650 IF1 DAC1 L Mux", "Slot0", "IF1 DAC0" },
265821ab3f2bSBard Liao { "RT5650 IF1 DAC1 L Mux", "Slot1", "IF1 DAC1" },
265921ab3f2bSBard Liao { "RT5650 IF1 DAC1 L Mux", "Slot2", "IF1 DAC2" },
266021ab3f2bSBard Liao { "RT5650 IF1 DAC1 L Mux", "Slot3", "IF1 DAC3" },
266121ab3f2bSBard Liao
266221ab3f2bSBard Liao { "RT5650 IF1 DAC1 R Mux", "Slot0", "IF1 DAC0" },
266321ab3f2bSBard Liao { "RT5650 IF1 DAC1 R Mux", "Slot1", "IF1 DAC1" },
266421ab3f2bSBard Liao { "RT5650 IF1 DAC1 R Mux", "Slot2", "IF1 DAC2" },
266521ab3f2bSBard Liao { "RT5650 IF1 DAC1 R Mux", "Slot3", "IF1 DAC3" },
266621ab3f2bSBard Liao
266721ab3f2bSBard Liao { "RT5650 IF1 DAC2 L Mux", "Slot0", "IF1 DAC0" },
266821ab3f2bSBard Liao { "RT5650 IF1 DAC2 L Mux", "Slot1", "IF1 DAC1" },
266921ab3f2bSBard Liao { "RT5650 IF1 DAC2 L Mux", "Slot2", "IF1 DAC2" },
267021ab3f2bSBard Liao { "RT5650 IF1 DAC2 L Mux", "Slot3", "IF1 DAC3" },
267121ab3f2bSBard Liao
267221ab3f2bSBard Liao { "RT5650 IF1 DAC2 R Mux", "Slot0", "IF1 DAC0" },
267321ab3f2bSBard Liao { "RT5650 IF1 DAC2 R Mux", "Slot1", "IF1 DAC1" },
267421ab3f2bSBard Liao { "RT5650 IF1 DAC2 R Mux", "Slot2", "IF1 DAC2" },
267521ab3f2bSBard Liao { "RT5650 IF1 DAC2 R Mux", "Slot3", "IF1 DAC3" },
267621ab3f2bSBard Liao
267721ab3f2bSBard Liao { "DAC1 L Mux", "IF1 DAC", "RT5650 IF1 DAC1 L Mux" },
267821ab3f2bSBard Liao { "DAC1 R Mux", "IF1 DAC", "RT5650 IF1 DAC1 R Mux" },
267921ab3f2bSBard Liao
268021ab3f2bSBard Liao { "DAC L2 Mux", "IF1 DAC", "RT5650 IF1 DAC2 L Mux" },
268121ab3f2bSBard Liao { "DAC R2 Mux", "IF1 DAC", "RT5650 IF1 DAC2 R Mux" },
26825c4ca99dSBard Liao };
26835c4ca99dSBard Liao
26845c4ca99dSBard Liao static const struct snd_soc_dapm_route rt5645_specific_dapm_routes[] = {
26855c4ca99dSBard Liao { "DAC L1", NULL, "Stereo DAC MIXL" },
26865c4ca99dSBard Liao { "DAC R1", NULL, "Stereo DAC MIXR" },
26875c4ca99dSBard Liao { "DAC L2", NULL, "Mono DAC MIXL" },
26885c4ca99dSBard Liao { "DAC R2", NULL, "Mono DAC MIXR" },
268921ab3f2bSBard Liao
269021ab3f2bSBard Liao { "RT5645 IF1 ADC1 Swap Mux", "L/R", "IF_ADC1" },
269121ab3f2bSBard Liao { "RT5645 IF1 ADC1 Swap Mux", "R/L", "IF_ADC1" },
269221ab3f2bSBard Liao { "RT5645 IF1 ADC1 Swap Mux", "L/L", "IF_ADC1" },
269321ab3f2bSBard Liao { "RT5645 IF1 ADC1 Swap Mux", "R/R", "IF_ADC1" },
269421ab3f2bSBard Liao
269521ab3f2bSBard Liao { "RT5645 IF1 ADC2 Swap Mux", "L/R", "IF_ADC2" },
269621ab3f2bSBard Liao { "RT5645 IF1 ADC2 Swap Mux", "R/L", "IF_ADC2" },
269721ab3f2bSBard Liao { "RT5645 IF1 ADC2 Swap Mux", "L/L", "IF_ADC2" },
269821ab3f2bSBard Liao { "RT5645 IF1 ADC2 Swap Mux", "R/R", "IF_ADC2" },
269921ab3f2bSBard Liao
270021ab3f2bSBard Liao { "RT5645 IF1 ADC3 Swap Mux", "L/R", "VAD_ADC" },
270121ab3f2bSBard Liao { "RT5645 IF1 ADC3 Swap Mux", "R/L", "VAD_ADC" },
270221ab3f2bSBard Liao { "RT5645 IF1 ADC3 Swap Mux", "L/L", "VAD_ADC" },
270321ab3f2bSBard Liao { "RT5645 IF1 ADC3 Swap Mux", "R/R", "VAD_ADC" },
270421ab3f2bSBard Liao
270521ab3f2bSBard Liao { "IF1 ADC", NULL, "RT5645 IF1 ADC1 Swap Mux" },
270621ab3f2bSBard Liao { "IF1 ADC", NULL, "RT5645 IF1 ADC2 Swap Mux" },
270721ab3f2bSBard Liao { "IF1 ADC", NULL, "RT5645 IF1 ADC3 Swap Mux" },
270821ab3f2bSBard Liao
270921ab3f2bSBard Liao { "RT5645 IF1 ADC Mux", "IF_ADC1/IF_ADC2/VAD_ADC", "IF1 ADC" },
271021ab3f2bSBard Liao { "RT5645 IF1 ADC Mux", "IF_ADC2/IF_ADC1/VAD_ADC", "IF1 ADC" },
271121ab3f2bSBard Liao { "RT5645 IF1 ADC Mux", "VAD_ADC/IF_ADC1/IF_ADC2", "IF1 ADC" },
271221ab3f2bSBard Liao { "RT5645 IF1 ADC Mux", "VAD_ADC/IF_ADC2/IF_ADC1", "IF1 ADC" },
271321ab3f2bSBard Liao { "AIF1TX", NULL, "RT5645 IF1 ADC Mux" },
271421ab3f2bSBard Liao
271521ab3f2bSBard Liao { "RT5645 IF1 DAC1 L Mux", "Slot0", "IF1 DAC0" },
271621ab3f2bSBard Liao { "RT5645 IF1 DAC1 L Mux", "Slot1", "IF1 DAC1" },
271721ab3f2bSBard Liao { "RT5645 IF1 DAC1 L Mux", "Slot2", "IF1 DAC2" },
271821ab3f2bSBard Liao { "RT5645 IF1 DAC1 L Mux", "Slot3", "IF1 DAC3" },
271921ab3f2bSBard Liao
272021ab3f2bSBard Liao { "RT5645 IF1 DAC1 R Mux", "Slot0", "IF1 DAC0" },
272121ab3f2bSBard Liao { "RT5645 IF1 DAC1 R Mux", "Slot1", "IF1 DAC1" },
272221ab3f2bSBard Liao { "RT5645 IF1 DAC1 R Mux", "Slot2", "IF1 DAC2" },
272321ab3f2bSBard Liao { "RT5645 IF1 DAC1 R Mux", "Slot3", "IF1 DAC3" },
272421ab3f2bSBard Liao
272521ab3f2bSBard Liao { "RT5645 IF1 DAC2 L Mux", "Slot0", "IF1 DAC0" },
272621ab3f2bSBard Liao { "RT5645 IF1 DAC2 L Mux", "Slot1", "IF1 DAC1" },
272721ab3f2bSBard Liao { "RT5645 IF1 DAC2 L Mux", "Slot2", "IF1 DAC2" },
272821ab3f2bSBard Liao { "RT5645 IF1 DAC2 L Mux", "Slot3", "IF1 DAC3" },
272921ab3f2bSBard Liao
273021ab3f2bSBard Liao { "RT5645 IF1 DAC2 R Mux", "Slot0", "IF1 DAC0" },
273121ab3f2bSBard Liao { "RT5645 IF1 DAC2 R Mux", "Slot1", "IF1 DAC1" },
273221ab3f2bSBard Liao { "RT5645 IF1 DAC2 R Mux", "Slot2", "IF1 DAC2" },
273321ab3f2bSBard Liao { "RT5645 IF1 DAC2 R Mux", "Slot3", "IF1 DAC3" },
273421ab3f2bSBard Liao
273521ab3f2bSBard Liao { "DAC1 L Mux", "IF1 DAC", "RT5645 IF1 DAC1 L Mux" },
273621ab3f2bSBard Liao { "DAC1 R Mux", "IF1 DAC", "RT5645 IF1 DAC1 R Mux" },
273721ab3f2bSBard Liao
273821ab3f2bSBard Liao { "DAC L2 Mux", "IF1 DAC", "RT5645 IF1 DAC2 L Mux" },
273921ab3f2bSBard Liao { "DAC R2 Mux", "IF1 DAC", "RT5645 IF1 DAC2 R Mux" },
27405c4ca99dSBard Liao };
27415c4ca99dSBard Liao
274250f510a3SBard Liao static const struct snd_soc_dapm_route rt5645_old_dapm_routes[] = {
274350f510a3SBard Liao { "SPOL MIX", "DAC R1 Switch", "DAC R1" },
274450f510a3SBard Liao { "SPOL MIX", "SPKVOL R Switch", "SPKVOL R" },
274550f510a3SBard Liao };
274650f510a3SBard Liao
rt5645_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)27471319b2f6SOder Chiou static int rt5645_hw_params(struct snd_pcm_substream *substream,
27481319b2f6SOder Chiou struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
27491319b2f6SOder Chiou {
275079223bf1SKuninori Morimoto struct snd_soc_component *component = dai->component;
275179223bf1SKuninori Morimoto struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
275257bf2736SBard Liao unsigned int val_len = 0, val_clk, mask_clk, dl_sft;
27531319b2f6SOder Chiou int pre_div, bclk_ms, frame_size;
27541319b2f6SOder Chiou
27551319b2f6SOder Chiou rt5645->lrck[dai->id] = params_rate(params);
2756d92950e7SOder Chiou pre_div = rl6231_get_clk_info(rt5645->sysclk, rt5645->lrck[dai->id]);
27571319b2f6SOder Chiou if (pre_div < 0) {
275879223bf1SKuninori Morimoto dev_err(component->dev, "Unsupported clock setting\n");
27591319b2f6SOder Chiou return -EINVAL;
27601319b2f6SOder Chiou }
27611319b2f6SOder Chiou frame_size = snd_soc_params_to_frame_size(params);
27621319b2f6SOder Chiou if (frame_size < 0) {
276379223bf1SKuninori Morimoto dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
27641319b2f6SOder Chiou return -EINVAL;
27651319b2f6SOder Chiou }
276657bf2736SBard Liao
276757bf2736SBard Liao switch (rt5645->codec_type) {
276857bf2736SBard Liao case CODEC_TYPE_RT5650:
276957bf2736SBard Liao dl_sft = 4;
277057bf2736SBard Liao break;
277157bf2736SBard Liao default:
277257bf2736SBard Liao dl_sft = 2;
277357bf2736SBard Liao break;
277457bf2736SBard Liao }
277557bf2736SBard Liao
27761319b2f6SOder Chiou bclk_ms = frame_size > 32;
27771319b2f6SOder Chiou rt5645->bclk[dai->id] = rt5645->lrck[dai->id] * (32 << bclk_ms);
27781319b2f6SOder Chiou
27791319b2f6SOder Chiou dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n",
27801319b2f6SOder Chiou rt5645->bclk[dai->id], rt5645->lrck[dai->id]);
27811319b2f6SOder Chiou dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
27821319b2f6SOder Chiou bclk_ms, pre_div, dai->id);
27831319b2f6SOder Chiou
27841319b2f6SOder Chiou switch (params_width(params)) {
27851319b2f6SOder Chiou case 16:
27861319b2f6SOder Chiou break;
27871319b2f6SOder Chiou case 20:
278857bf2736SBard Liao val_len = 0x1;
27891319b2f6SOder Chiou break;
27901319b2f6SOder Chiou case 24:
279157bf2736SBard Liao val_len = 0x2;
27921319b2f6SOder Chiou break;
27931319b2f6SOder Chiou case 8:
279457bf2736SBard Liao val_len = 0x3;
27951319b2f6SOder Chiou break;
27961319b2f6SOder Chiou default:
27971319b2f6SOder Chiou return -EINVAL;
27981319b2f6SOder Chiou }
27991319b2f6SOder Chiou
28001319b2f6SOder Chiou switch (dai->id) {
28011319b2f6SOder Chiou case RT5645_AIF1:
280233de3d54SBard Liao mask_clk = RT5645_I2S_PD1_MASK;
280333de3d54SBard Liao val_clk = pre_div << RT5645_I2S_PD1_SFT;
280479223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_I2S1_SDP,
280557bf2736SBard Liao (0x3 << dl_sft), (val_len << dl_sft));
280679223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_ADDA_CLK1, mask_clk, val_clk);
28071319b2f6SOder Chiou break;
28081319b2f6SOder Chiou case RT5645_AIF2:
28091319b2f6SOder Chiou mask_clk = RT5645_I2S_BCLK_MS2_MASK | RT5645_I2S_PD2_MASK;
28101319b2f6SOder Chiou val_clk = bclk_ms << RT5645_I2S_BCLK_MS2_SFT |
28111319b2f6SOder Chiou pre_div << RT5645_I2S_PD2_SFT;
281279223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_I2S2_SDP,
281357bf2736SBard Liao (0x3 << dl_sft), (val_len << dl_sft));
281479223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_ADDA_CLK1, mask_clk, val_clk);
28151319b2f6SOder Chiou break;
28161319b2f6SOder Chiou default:
281779223bf1SKuninori Morimoto dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
28181319b2f6SOder Chiou return -EINVAL;
28191319b2f6SOder Chiou }
28201319b2f6SOder Chiou
28211319b2f6SOder Chiou return 0;
28221319b2f6SOder Chiou }
28231319b2f6SOder Chiou
rt5645_set_dai_fmt(struct snd_soc_dai * dai,unsigned int fmt)28241319b2f6SOder Chiou static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
28251319b2f6SOder Chiou {
282679223bf1SKuninori Morimoto struct snd_soc_component *component = dai->component;
282779223bf1SKuninori Morimoto struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
282857bf2736SBard Liao unsigned int reg_val = 0, pol_sft;
282957bf2736SBard Liao
283057bf2736SBard Liao switch (rt5645->codec_type) {
283157bf2736SBard Liao case CODEC_TYPE_RT5650:
283257bf2736SBard Liao pol_sft = 8;
283357bf2736SBard Liao break;
283457bf2736SBard Liao default:
283557bf2736SBard Liao pol_sft = 7;
283657bf2736SBard Liao break;
283757bf2736SBard Liao }
28381319b2f6SOder Chiou
28391319b2f6SOder Chiou switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
28401319b2f6SOder Chiou case SND_SOC_DAIFMT_CBM_CFM:
28411319b2f6SOder Chiou rt5645->master[dai->id] = 1;
28421319b2f6SOder Chiou break;
28431319b2f6SOder Chiou case SND_SOC_DAIFMT_CBS_CFS:
28441319b2f6SOder Chiou reg_val |= RT5645_I2S_MS_S;
28451319b2f6SOder Chiou rt5645->master[dai->id] = 0;
28461319b2f6SOder Chiou break;
28471319b2f6SOder Chiou default:
28481319b2f6SOder Chiou return -EINVAL;
28491319b2f6SOder Chiou }
28501319b2f6SOder Chiou
28511319b2f6SOder Chiou switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
28521319b2f6SOder Chiou case SND_SOC_DAIFMT_NB_NF:
28531319b2f6SOder Chiou break;
28541319b2f6SOder Chiou case SND_SOC_DAIFMT_IB_NF:
285557bf2736SBard Liao reg_val |= (1 << pol_sft);
28561319b2f6SOder Chiou break;
28571319b2f6SOder Chiou default:
28581319b2f6SOder Chiou return -EINVAL;
28591319b2f6SOder Chiou }
28601319b2f6SOder Chiou
28611319b2f6SOder Chiou switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
28621319b2f6SOder Chiou case SND_SOC_DAIFMT_I2S:
28631319b2f6SOder Chiou break;
28641319b2f6SOder Chiou case SND_SOC_DAIFMT_LEFT_J:
28651319b2f6SOder Chiou reg_val |= RT5645_I2S_DF_LEFT;
28661319b2f6SOder Chiou break;
28671319b2f6SOder Chiou case SND_SOC_DAIFMT_DSP_A:
28681319b2f6SOder Chiou reg_val |= RT5645_I2S_DF_PCM_A;
28691319b2f6SOder Chiou break;
28701319b2f6SOder Chiou case SND_SOC_DAIFMT_DSP_B:
28711319b2f6SOder Chiou reg_val |= RT5645_I2S_DF_PCM_B;
28721319b2f6SOder Chiou break;
28731319b2f6SOder Chiou default:
28741319b2f6SOder Chiou return -EINVAL;
28751319b2f6SOder Chiou }
28761319b2f6SOder Chiou switch (dai->id) {
28771319b2f6SOder Chiou case RT5645_AIF1:
287879223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_I2S1_SDP,
287957bf2736SBard Liao RT5645_I2S_MS_MASK | (1 << pol_sft) |
28801319b2f6SOder Chiou RT5645_I2S_DF_MASK, reg_val);
28811319b2f6SOder Chiou break;
28821319b2f6SOder Chiou case RT5645_AIF2:
288379223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_I2S2_SDP,
288457bf2736SBard Liao RT5645_I2S_MS_MASK | (1 << pol_sft) |
28851319b2f6SOder Chiou RT5645_I2S_DF_MASK, reg_val);
28861319b2f6SOder Chiou break;
28871319b2f6SOder Chiou default:
288879223bf1SKuninori Morimoto dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
28891319b2f6SOder Chiou return -EINVAL;
28901319b2f6SOder Chiou }
28911319b2f6SOder Chiou return 0;
28921319b2f6SOder Chiou }
28931319b2f6SOder Chiou
rt5645_set_dai_sysclk(struct snd_soc_dai * dai,int clk_id,unsigned int freq,int dir)28941319b2f6SOder Chiou static int rt5645_set_dai_sysclk(struct snd_soc_dai *dai,
28951319b2f6SOder Chiou int clk_id, unsigned int freq, int dir)
28961319b2f6SOder Chiou {
289779223bf1SKuninori Morimoto struct snd_soc_component *component = dai->component;
289879223bf1SKuninori Morimoto struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
28991319b2f6SOder Chiou unsigned int reg_val = 0;
29001319b2f6SOder Chiou
29011319b2f6SOder Chiou if (freq == rt5645->sysclk && clk_id == rt5645->sysclk_src)
29021319b2f6SOder Chiou return 0;
29031319b2f6SOder Chiou
29041319b2f6SOder Chiou switch (clk_id) {
29051319b2f6SOder Chiou case RT5645_SCLK_S_MCLK:
29061319b2f6SOder Chiou reg_val |= RT5645_SCLK_SRC_MCLK;
29071319b2f6SOder Chiou break;
29081319b2f6SOder Chiou case RT5645_SCLK_S_PLL1:
29091319b2f6SOder Chiou reg_val |= RT5645_SCLK_SRC_PLL1;
29101319b2f6SOder Chiou break;
29111319b2f6SOder Chiou case RT5645_SCLK_S_RCCLK:
29121319b2f6SOder Chiou reg_val |= RT5645_SCLK_SRC_RCCLK;
29131319b2f6SOder Chiou break;
29141319b2f6SOder Chiou default:
291579223bf1SKuninori Morimoto dev_err(component->dev, "Invalid clock id (%d)\n", clk_id);
29161319b2f6SOder Chiou return -EINVAL;
29171319b2f6SOder Chiou }
291879223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_GLB_CLK,
29191319b2f6SOder Chiou RT5645_SCLK_SRC_MASK, reg_val);
29201319b2f6SOder Chiou rt5645->sysclk = freq;
29211319b2f6SOder Chiou rt5645->sysclk_src = clk_id;
29221319b2f6SOder Chiou
29231319b2f6SOder Chiou dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id);
29241319b2f6SOder Chiou
29251319b2f6SOder Chiou return 0;
29261319b2f6SOder Chiou }
29271319b2f6SOder Chiou
rt5645_set_dai_pll(struct snd_soc_dai * dai,int pll_id,int source,unsigned int freq_in,unsigned int freq_out)29281319b2f6SOder Chiou static int rt5645_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
29291319b2f6SOder Chiou unsigned int freq_in, unsigned int freq_out)
29301319b2f6SOder Chiou {
293179223bf1SKuninori Morimoto struct snd_soc_component *component = dai->component;
293279223bf1SKuninori Morimoto struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
293371c7a2d6SOder Chiou struct rl6231_pll_code pll_code;
29341319b2f6SOder Chiou int ret;
29351319b2f6SOder Chiou
29361319b2f6SOder Chiou if (source == rt5645->pll_src && freq_in == rt5645->pll_in &&
29371319b2f6SOder Chiou freq_out == rt5645->pll_out)
29381319b2f6SOder Chiou return 0;
29391319b2f6SOder Chiou
29401319b2f6SOder Chiou if (!freq_in || !freq_out) {
294179223bf1SKuninori Morimoto dev_dbg(component->dev, "PLL disabled\n");
29421319b2f6SOder Chiou
29431319b2f6SOder Chiou rt5645->pll_in = 0;
29441319b2f6SOder Chiou rt5645->pll_out = 0;
294579223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_GLB_CLK,
29461319b2f6SOder Chiou RT5645_SCLK_SRC_MASK, RT5645_SCLK_SRC_MCLK);
29471319b2f6SOder Chiou return 0;
29481319b2f6SOder Chiou }
29491319b2f6SOder Chiou
29501319b2f6SOder Chiou switch (source) {
29511319b2f6SOder Chiou case RT5645_PLL1_S_MCLK:
295279223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_GLB_CLK,
29531319b2f6SOder Chiou RT5645_PLL1_SRC_MASK, RT5645_PLL1_SRC_MCLK);
29541319b2f6SOder Chiou break;
29551319b2f6SOder Chiou case RT5645_PLL1_S_BCLK1:
29561319b2f6SOder Chiou case RT5645_PLL1_S_BCLK2:
29571319b2f6SOder Chiou switch (dai->id) {
29581319b2f6SOder Chiou case RT5645_AIF1:
295979223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_GLB_CLK,
29601319b2f6SOder Chiou RT5645_PLL1_SRC_MASK, RT5645_PLL1_SRC_BCLK1);
29611319b2f6SOder Chiou break;
29621319b2f6SOder Chiou case RT5645_AIF2:
296379223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_GLB_CLK,
29641319b2f6SOder Chiou RT5645_PLL1_SRC_MASK, RT5645_PLL1_SRC_BCLK2);
29651319b2f6SOder Chiou break;
29661319b2f6SOder Chiou default:
296779223bf1SKuninori Morimoto dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
29681319b2f6SOder Chiou return -EINVAL;
29691319b2f6SOder Chiou }
29701319b2f6SOder Chiou break;
29711319b2f6SOder Chiou default:
297279223bf1SKuninori Morimoto dev_err(component->dev, "Unknown PLL source %d\n", source);
29731319b2f6SOder Chiou return -EINVAL;
29741319b2f6SOder Chiou }
29751319b2f6SOder Chiou
297671c7a2d6SOder Chiou ret = rl6231_pll_calc(freq_in, freq_out, &pll_code);
29771319b2f6SOder Chiou if (ret < 0) {
2978a4db95b2SColin Ian King dev_err(component->dev, "Unsupported input clock %d\n", freq_in);
29791319b2f6SOder Chiou return ret;
29801319b2f6SOder Chiou }
29811319b2f6SOder Chiou
298279223bf1SKuninori Morimoto dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n",
29831319b2f6SOder Chiou pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
29841319b2f6SOder Chiou pll_code.n_code, pll_code.k_code);
29851319b2f6SOder Chiou
298679223bf1SKuninori Morimoto snd_soc_component_write(component, RT5645_PLL_CTRL1,
29871319b2f6SOder Chiou pll_code.n_code << RT5645_PLL_N_SFT | pll_code.k_code);
298879223bf1SKuninori Morimoto snd_soc_component_write(component, RT5645_PLL_CTRL2,
2989fa0eb20cSPierre-Louis Bossart ((pll_code.m_bp ? 0 : pll_code.m_code) << RT5645_PLL_M_SFT) |
2990fa0eb20cSPierre-Louis Bossart (pll_code.m_bp << RT5645_PLL_M_BP_SFT));
29911319b2f6SOder Chiou
29921319b2f6SOder Chiou rt5645->pll_in = freq_in;
29931319b2f6SOder Chiou rt5645->pll_out = freq_out;
29941319b2f6SOder Chiou rt5645->pll_src = source;
29951319b2f6SOder Chiou
29961319b2f6SOder Chiou return 0;
29971319b2f6SOder Chiou }
29981319b2f6SOder Chiou
rt5645_set_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)29991319b2f6SOder Chiou static int rt5645_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
30001319b2f6SOder Chiou unsigned int rx_mask, int slots, int slot_width)
30011319b2f6SOder Chiou {
300279223bf1SKuninori Morimoto struct snd_soc_component *component = dai->component;
300379223bf1SKuninori Morimoto struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
300442ce5b8aSBard Liao unsigned int i_slot_sft, o_slot_sft, i_width_sht, o_width_sht, en_sft;
300542ce5b8aSBard Liao unsigned int mask, val = 0;
30061319b2f6SOder Chiou
300742ce5b8aSBard Liao switch (rt5645->codec_type) {
300842ce5b8aSBard Liao case CODEC_TYPE_RT5650:
300942ce5b8aSBard Liao en_sft = 15;
301042ce5b8aSBard Liao i_slot_sft = 10;
301142ce5b8aSBard Liao o_slot_sft = 8;
301242ce5b8aSBard Liao i_width_sht = 6;
301342ce5b8aSBard Liao o_width_sht = 4;
301442ce5b8aSBard Liao mask = 0x8ff0;
301542ce5b8aSBard Liao break;
301642ce5b8aSBard Liao default:
301742ce5b8aSBard Liao en_sft = 14;
301842ce5b8aSBard Liao i_slot_sft = o_slot_sft = 12;
301942ce5b8aSBard Liao i_width_sht = o_width_sht = 10;
302042ce5b8aSBard Liao mask = 0x7c00;
302142ce5b8aSBard Liao break;
302242ce5b8aSBard Liao }
3023850577dbSBard Liao if (rx_mask || tx_mask) {
302442ce5b8aSBard Liao val |= (1 << en_sft);
302542ce5b8aSBard Liao if (rt5645->codec_type == CODEC_TYPE_RT5645)
302679223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_BASS_BACK,
3027850577dbSBard Liao RT5645_G_BB_BST_MASK, RT5645_G_BB_BST_25DB);
3028850577dbSBard Liao }
30291319b2f6SOder Chiou
30301319b2f6SOder Chiou switch (slots) {
30311319b2f6SOder Chiou case 4:
303242ce5b8aSBard Liao val |= (1 << i_slot_sft) | (1 << o_slot_sft);
30331319b2f6SOder Chiou break;
30341319b2f6SOder Chiou case 6:
303542ce5b8aSBard Liao val |= (2 << i_slot_sft) | (2 << o_slot_sft);
30361319b2f6SOder Chiou break;
30371319b2f6SOder Chiou case 8:
303842ce5b8aSBard Liao val |= (3 << i_slot_sft) | (3 << o_slot_sft);
30391319b2f6SOder Chiou break;
30401319b2f6SOder Chiou case 2:
30411319b2f6SOder Chiou default:
30421319b2f6SOder Chiou break;
30431319b2f6SOder Chiou }
30441319b2f6SOder Chiou
30451319b2f6SOder Chiou switch (slot_width) {
30461319b2f6SOder Chiou case 20:
304742ce5b8aSBard Liao val |= (1 << i_width_sht) | (1 << o_width_sht);
30481319b2f6SOder Chiou break;
30491319b2f6SOder Chiou case 24:
305042ce5b8aSBard Liao val |= (2 << i_width_sht) | (2 << o_width_sht);
30511319b2f6SOder Chiou break;
30521319b2f6SOder Chiou case 32:
305342ce5b8aSBard Liao val |= (3 << i_width_sht) | (3 << o_width_sht);
30541319b2f6SOder Chiou break;
30551319b2f6SOder Chiou case 16:
30561319b2f6SOder Chiou default:
30571319b2f6SOder Chiou break;
30581319b2f6SOder Chiou }
30591319b2f6SOder Chiou
306079223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_TDM_CTRL_1, mask, val);
30611319b2f6SOder Chiou
30621319b2f6SOder Chiou return 0;
30631319b2f6SOder Chiou }
30641319b2f6SOder Chiou
rt5645_set_bias_level(struct snd_soc_component * component,enum snd_soc_bias_level level)306579223bf1SKuninori Morimoto static int rt5645_set_bias_level(struct snd_soc_component *component,
30661319b2f6SOder Chiou enum snd_soc_bias_level level)
30671319b2f6SOder Chiou {
306879223bf1SKuninori Morimoto struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
30696e747d53SBard Liao
30701319b2f6SOder Chiou switch (level) {
30710b2e4959SBard Liao case SND_SOC_BIAS_PREPARE:
307279223bf1SKuninori Morimoto if (SND_SOC_BIAS_STANDBY == snd_soc_component_get_bias_level(component)) {
307379223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
30741319b2f6SOder Chiou RT5645_PWR_VREF1 | RT5645_PWR_MB |
30751319b2f6SOder Chiou RT5645_PWR_BG | RT5645_PWR_VREF2,
30761319b2f6SOder Chiou RT5645_PWR_VREF1 | RT5645_PWR_MB |
30771319b2f6SOder Chiou RT5645_PWR_BG | RT5645_PWR_VREF2);
30781319b2f6SOder Chiou mdelay(10);
307979223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
30801319b2f6SOder Chiou RT5645_PWR_FV1 | RT5645_PWR_FV2,
30811319b2f6SOder Chiou RT5645_PWR_FV1 | RT5645_PWR_FV2);
308279223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_GEN_CTRL1,
30831319b2f6SOder Chiou RT5645_DIG_GATE_CTRL, RT5645_DIG_GATE_CTRL);
30841319b2f6SOder Chiou }
30851319b2f6SOder Chiou break;
30861319b2f6SOder Chiou
30870b2e4959SBard Liao case SND_SOC_BIAS_STANDBY:
308879223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
30890b2e4959SBard Liao RT5645_PWR_VREF1 | RT5645_PWR_MB |
30900b2e4959SBard Liao RT5645_PWR_BG | RT5645_PWR_VREF2,
30910b2e4959SBard Liao RT5645_PWR_VREF1 | RT5645_PWR_MB |
30920b2e4959SBard Liao RT5645_PWR_BG | RT5645_PWR_VREF2);
30930150e8c0SJohn Lin mdelay(10);
309479223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
30950b2e4959SBard Liao RT5645_PWR_FV1 | RT5645_PWR_FV2,
30960b2e4959SBard Liao RT5645_PWR_FV1 | RT5645_PWR_FV2);
309779223bf1SKuninori Morimoto if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {
309879223bf1SKuninori Morimoto snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1140);
30990150e8c0SJohn Lin msleep(40);
31000150e8c0SJohn Lin if (rt5645->en_button_func)
3101c962d03bSOder Chiou queue_delayed_work(system_power_efficient_wq,
31020150e8c0SJohn Lin &rt5645->jack_detect_work,
31030150e8c0SJohn Lin msecs_to_jiffies(0));
31040150e8c0SJohn Lin }
31050b2e4959SBard Liao break;
31060b2e4959SBard Liao
31071319b2f6SOder Chiou case SND_SOC_BIAS_OFF:
310879223bf1SKuninori Morimoto snd_soc_component_write(component, RT5645_DEPOP_M2, 0x1100);
31096e747d53SBard Liao if (!rt5645->en_button_func)
311079223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_GEN_CTRL1,
31111b5d0160SBard Liao RT5645_DIG_GATE_CTRL, 0);
311279223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_PWR_ANLG1,
31130b2e4959SBard Liao RT5645_PWR_VREF1 | RT5645_PWR_MB |
31140b2e4959SBard Liao RT5645_PWR_BG | RT5645_PWR_VREF2 |
31150b2e4959SBard Liao RT5645_PWR_FV1 | RT5645_PWR_FV2, 0x0);
31161319b2f6SOder Chiou break;
31171319b2f6SOder Chiou
31181319b2f6SOder Chiou default:
31191319b2f6SOder Chiou break;
31201319b2f6SOder Chiou }
31211319b2f6SOder Chiou
31221319b2f6SOder Chiou return 0;
31231319b2f6SOder Chiou }
31241319b2f6SOder Chiou
rt5645_enable_push_button_irq(struct snd_soc_component * component,bool enable)312579223bf1SKuninori Morimoto static void rt5645_enable_push_button_irq(struct snd_soc_component *component,
31266e747d53SBard Liao bool enable)
3127f3fa1bbdSOder Chiou {
312879223bf1SKuninori Morimoto struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
31296e747d53SBard Liao
31306e747d53SBard Liao if (enable) {
3131a4e3c5faSNicolas Boichat snd_soc_dapm_force_enable_pin(dapm, "ADC L power");
3132a4e3c5faSNicolas Boichat snd_soc_dapm_force_enable_pin(dapm, "ADC R power");
3133a4e3c5faSNicolas Boichat snd_soc_dapm_sync(dapm);
313422f5d9f8SNicolas Boichat
313579223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5650_4BTN_IL_CMD1, 0x3, 0x3);
313679223bf1SKuninori Morimoto snd_soc_component_update_bits(component,
31376e747d53SBard Liao RT5645_INT_IRQ_ST, 0x8, 0x8);
313879223bf1SKuninori Morimoto snd_soc_component_update_bits(component,
31396e747d53SBard Liao RT5650_4BTN_IL_CMD2, 0x8000, 0x8000);
3140467a2553SKuninori Morimoto snd_soc_component_read(component, RT5650_4BTN_IL_CMD1);
31416e747d53SBard Liao pr_debug("%s read %x = %x\n", __func__, RT5650_4BTN_IL_CMD1,
3142467a2553SKuninori Morimoto snd_soc_component_read(component, RT5650_4BTN_IL_CMD1));
31436e747d53SBard Liao } else {
314479223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5650_4BTN_IL_CMD2, 0x8000, 0x0);
314579223bf1SKuninori Morimoto snd_soc_component_update_bits(component, RT5645_INT_IRQ_ST, 0x8, 0x0);
314622f5d9f8SNicolas Boichat
3147a4e3c5faSNicolas Boichat snd_soc_dapm_disable_pin(dapm, "ADC L power");
3148a4e3c5faSNicolas Boichat snd_soc_dapm_disable_pin(dapm, "ADC R power");
3149a4e3c5faSNicolas Boichat snd_soc_dapm_sync(dapm);
31506e747d53SBard Liao }
31516e747d53SBard Liao }
31526e747d53SBard Liao
rt5645_jack_detect(struct snd_soc_component * component,int jack_insert)315379223bf1SKuninori Morimoto static int rt5645_jack_detect(struct snd_soc_component *component, int jack_insert)
31546e747d53SBard Liao {
315579223bf1SKuninori Morimoto struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
315679223bf1SKuninori Morimoto struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
3157f3fa1bbdSOder Chiou unsigned int val;
3158f3fa1bbdSOder Chiou
31596e747d53SBard Liao if (jack_insert) {
3160aa98697cSShuming Fan regmap_write(rt5645->regmap, RT5645_CHARGE_PUMP, 0x0206);
316105a9b46aSJohn Lin
316205a9b46aSJohn Lin /* for jack type detect */
3163e2ada818SLars-Peter Clausen snd_soc_dapm_force_enable_pin(dapm, "LDO2");
3164e2ada818SLars-Peter Clausen snd_soc_dapm_force_enable_pin(dapm, "Mic Det Power");
3165e2ada818SLars-Peter Clausen snd_soc_dapm_sync(dapm);
31668ec35236SKuninori Morimoto if (!snd_soc_card_is_instantiated(dapm->card)) {
31676e747d53SBard Liao /* Power up necessary bits for JD if dapm is
31686e747d53SBard Liao not ready yet */
316905a9b46aSJohn Lin regmap_update_bits(rt5645->regmap, RT5645_PWR_ANLG1,
317005a9b46aSJohn Lin RT5645_PWR_MB | RT5645_PWR_VREF2,
317105a9b46aSJohn Lin RT5645_PWR_MB | RT5645_PWR_VREF2);
317205a9b46aSJohn Lin regmap_update_bits(rt5645->regmap, RT5645_PWR_MIXER,
31736e747d53SBard Liao RT5645_PWR_LDO2, RT5645_PWR_LDO2);
317405a9b46aSJohn Lin regmap_update_bits(rt5645->regmap, RT5645_PWR_VOL,
31756e747d53SBard Liao RT5645_PWR_MIC_DET, RT5645_PWR_MIC_DET);
31766e747d53SBard Liao }
3177f3fa1bbdSOder Chiou
317805a9b46aSJohn Lin regmap_write(rt5645->regmap, RT5645_JD_CTRL3, 0x00f0);
3179f2988afeSOder Chiou regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL2,
3180f2988afeSOder Chiou RT5645_CBJ_MN_JD, RT5645_CBJ_MN_JD);
3181f2988afeSOder Chiou regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1,
3182f2988afeSOder Chiou RT5645_CBJ_BST1_EN, RT5645_CBJ_BST1_EN);
318305a9b46aSJohn Lin msleep(100);
3184f2988afeSOder Chiou regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL2,
3185f2988afeSOder Chiou RT5645_CBJ_MN_JD, 0);
3186f3fa1bbdSOder Chiou
3187*7904b066SDerek Fang if (rt5645->gpiod_cbj_sleeve)
3188*7904b066SDerek Fang gpiod_set_value(rt5645->gpiod_cbj_sleeve, 1);
3189*7904b066SDerek Fang
31908db7f56dSOder Chiou msleep(600);
319105a9b46aSJohn Lin regmap_read(rt5645->regmap, RT5645_IN1_CTRL3, &val);
319205a9b46aSJohn Lin val &= 0x7;
319379223bf1SKuninori Morimoto dev_dbg(component->dev, "val = %d\n", val);
3194f3fa1bbdSOder Chiou
31953f004d2dSHans de Goede if ((val == 1 || val == 2) && !rt5645->pdata.no_headset_mic) {
31966e747d53SBard Liao rt5645->jack_type = SND_JACK_HEADSET;
31976e747d53SBard Liao if (rt5645->en_button_func) {
319879223bf1SKuninori Morimoto rt5645_enable_push_button_irq(component, true);
31996e747d53SBard Liao }
32006e747d53SBard Liao } else {
32018f82f2e4SShuming Fan if (rt5645->en_button_func)
32028f82f2e4SShuming Fan rt5645_enable_push_button_irq(component, false);
3203e2ada818SLars-Peter Clausen snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
3204e2ada818SLars-Peter Clausen snd_soc_dapm_sync(dapm);
32056e747d53SBard Liao rt5645->jack_type = SND_JACK_HEADPHONE;
3206*7904b066SDerek Fang if (rt5645->gpiod_cbj_sleeve)
3207*7904b066SDerek Fang gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
32086e747d53SBard Liao }
320989575022SBard Liao if (rt5645->pdata.level_trigger_irq)
3210917536aeSJohn Lin regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
32117ff6319eSBard Liao RT5645_JD_1_1_MASK, RT5645_JD_1_1_NOR);
3212aa98697cSShuming Fan
3213aa98697cSShuming Fan regmap_write(rt5645->regmap, RT5645_CHARGE_PUMP, 0x0e06);
32146e747d53SBard Liao } else { /* jack out */
32156e747d53SBard Liao rt5645->jack_type = 0;
3216a4e3c5faSNicolas Boichat
3217fce97b4dSOder Chiou regmap_update_bits(rt5645->regmap, RT5645_HP_VOL,
3218fce97b4dSOder Chiou RT5645_L_MUTE | RT5645_R_MUTE,
3219fce97b4dSOder Chiou RT5645_L_MUTE | RT5645_R_MUTE);
3220f2988afeSOder Chiou regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL2,
3221f2988afeSOder Chiou RT5645_CBJ_MN_JD, RT5645_CBJ_MN_JD);
3222f2988afeSOder Chiou regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1,
3223f2988afeSOder Chiou RT5645_CBJ_BST1_EN, 0);
32248db7f56dSOder Chiou
32256e747d53SBard Liao if (rt5645->en_button_func)
322679223bf1SKuninori Morimoto rt5645_enable_push_button_irq(component, false);
3227a4e3c5faSNicolas Boichat
3228b7f22478SJohn Lin if (rt5645->pdata.jd_mode == 0)
3229e2ada818SLars-Peter Clausen snd_soc_dapm_disable_pin(dapm, "LDO2");
3230e2ada818SLars-Peter Clausen snd_soc_dapm_disable_pin(dapm, "Mic Det Power");
3231e2ada818SLars-Peter Clausen snd_soc_dapm_sync(dapm);
323289575022SBard Liao if (rt5645->pdata.level_trigger_irq)
3233917536aeSJohn Lin regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
32347ff6319eSBard Liao RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
3235*7904b066SDerek Fang
3236*7904b066SDerek Fang if (rt5645->gpiod_cbj_sleeve)
3237*7904b066SDerek Fang gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
32386e747d53SBard Liao }
32396e747d53SBard Liao
32406e747d53SBard Liao return rt5645->jack_type;
3241f3fa1bbdSOder Chiou }
3242f3fa1bbdSOder Chiou
rt5645_button_detect(struct snd_soc_component * component)324379223bf1SKuninori Morimoto static int rt5645_button_detect(struct snd_soc_component *component)
3244f312bc59SNicolas Boichat {
3245f312bc59SNicolas Boichat int btn_type, val;
3246f312bc59SNicolas Boichat
3247467a2553SKuninori Morimoto val = snd_soc_component_read(component, RT5650_4BTN_IL_CMD1);
3248f312bc59SNicolas Boichat pr_debug("val=0x%x\n", val);
3249f312bc59SNicolas Boichat btn_type = val & 0xfff0;
325079223bf1SKuninori Morimoto snd_soc_component_write(component, RT5650_4BTN_IL_CMD1, val);
3251f312bc59SNicolas Boichat
3252f312bc59SNicolas Boichat return btn_type;
3253f312bc59SNicolas Boichat }
3254f312bc59SNicolas Boichat
3255345b0f50SJohn Lin static irqreturn_t rt5645_irq(int irq, void *data);
3256d5660422SBard Liao
rt5645_set_jack_detect(struct snd_soc_component * component,struct snd_soc_jack * hp_jack,struct snd_soc_jack * mic_jack,struct snd_soc_jack * btn_jack)325779223bf1SKuninori Morimoto int rt5645_set_jack_detect(struct snd_soc_component *component,
32586e747d53SBard Liao struct snd_soc_jack *hp_jack, struct snd_soc_jack *mic_jack,
32596e747d53SBard Liao struct snd_soc_jack *btn_jack)
3260f3fa1bbdSOder Chiou {
326179223bf1SKuninori Morimoto struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
3262f3fa1bbdSOder Chiou
3263471f208aSBard Liao rt5645->hp_jack = hp_jack;
3264471f208aSBard Liao rt5645->mic_jack = mic_jack;
32656e747d53SBard Liao rt5645->btn_jack = btn_jack;
32666e747d53SBard Liao if (rt5645->btn_jack && rt5645->codec_type == CODEC_TYPE_RT5650) {
32676e747d53SBard Liao rt5645->en_button_func = true;
32686e747d53SBard Liao regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1,
32696e747d53SBard Liao RT5645_GP1_PIN_IRQ, RT5645_GP1_PIN_IRQ);
32706e747d53SBard Liao regmap_update_bits(rt5645->regmap, RT5645_GEN_CTRL1,
32716e747d53SBard Liao RT5645_DIG_GATE_CTRL, RT5645_DIG_GATE_CTRL);
3272f88dfbf3SShuming Fan regmap_update_bits(rt5645->regmap, RT5645_DEPOP_M1,
3273f88dfbf3SShuming Fan RT5645_HP_CB_MASK, RT5645_HP_CB_PU);
32746e747d53SBard Liao }
3275345b0f50SJohn Lin rt5645_irq(0, rt5645);
3276f3fa1bbdSOder Chiou
3277f3fa1bbdSOder Chiou return 0;
3278f3fa1bbdSOder Chiou }
3279f3fa1bbdSOder Chiou EXPORT_SYMBOL_GPL(rt5645_set_jack_detect);
3280f3fa1bbdSOder Chiou
rt5645_component_set_jack(struct snd_soc_component * component,struct snd_soc_jack * hs_jack,void * data)32817f6ecc22SShuming Fan static int rt5645_component_set_jack(struct snd_soc_component *component,
32827f6ecc22SShuming Fan struct snd_soc_jack *hs_jack, void *data)
32837f6ecc22SShuming Fan {
32847f6ecc22SShuming Fan struct snd_soc_jack *mic_jack = NULL;
32857f6ecc22SShuming Fan struct snd_soc_jack *btn_jack = NULL;
32865366a640SBrent Lu int type;
32877f6ecc22SShuming Fan
32885366a640SBrent Lu if (hs_jack) {
32895366a640SBrent Lu type = *(int *)data;
32905366a640SBrent Lu
32915366a640SBrent Lu if (type & SND_JACK_MICROPHONE)
32927f6ecc22SShuming Fan mic_jack = hs_jack;
32935366a640SBrent Lu if (type & (SND_JACK_BTN_0 | SND_JACK_BTN_1 |
32947f6ecc22SShuming Fan SND_JACK_BTN_2 | SND_JACK_BTN_3))
32957f6ecc22SShuming Fan btn_jack = hs_jack;
32965366a640SBrent Lu }
32977f6ecc22SShuming Fan
32987f6ecc22SShuming Fan return rt5645_set_jack_detect(component, hs_jack, mic_jack, btn_jack);
32997f6ecc22SShuming Fan }
33007f6ecc22SShuming Fan
rt5645_jack_detect_work(struct work_struct * work)3301cd6e82b8SOder Chiou static void rt5645_jack_detect_work(struct work_struct *work)
3302cd6e82b8SOder Chiou {
3303cd6e82b8SOder Chiou struct rt5645_priv *rt5645 =
3304cd6e82b8SOder Chiou container_of(work, struct rt5645_priv, jack_detect_work.work);
33056e747d53SBard Liao int val, btn_type, gpio_state = 0, report = 0;
33066e747d53SBard Liao
330779223bf1SKuninori Morimoto if (!rt5645->component)
3308f136dce4SNicolas Boichat return;
3309f2a5ded3SNicolas Boichat
33108f82f2e4SShuming Fan mutex_lock(&rt5645->jd_mutex);
33118f82f2e4SShuming Fan
33126e747d53SBard Liao switch (rt5645->pdata.jd_mode) {
33136e747d53SBard Liao case 0: /* Not using rt5645 JD */
33140b0cefc8SOder Chiou if (rt5645->gpiod_hp_det) {
33150b0cefc8SOder Chiou gpio_state = gpiod_get_value(rt5645->gpiod_hp_det);
331628c98849SChris Chiu if (rt5645->pdata.inv_hp_pol)
331728c98849SChris Chiu gpio_state ^= 1;
331879223bf1SKuninori Morimoto dev_dbg(rt5645->component->dev, "gpio_state = %d\n",
33190b0cefc8SOder Chiou gpio_state);
332079223bf1SKuninori Morimoto report = rt5645_jack_detect(rt5645->component, gpio_state);
33216e747d53SBard Liao }
33226e747d53SBard Liao snd_soc_jack_report(rt5645->hp_jack,
33236e747d53SBard Liao report, SND_JACK_HEADPHONE);
33246e747d53SBard Liao snd_soc_jack_report(rt5645->mic_jack,
33256e747d53SBard Liao report, SND_JACK_MICROPHONE);
3326050ad2caSAlexey Khoroshilov mutex_unlock(&rt5645->jd_mutex);
3327f312bc59SNicolas Boichat return;
3328e7cfd867SJacob Rasmussen case 4:
3329467a2553SKuninori Morimoto val = snd_soc_component_read(rt5645->component, RT5645_A_JD_CTRL1) & 0x0020;
3330e7cfd867SJacob Rasmussen break;
33316b5da663SBard Liao default: /* read rt5645 jd1_1 status */
3332467a2553SKuninori Morimoto val = snd_soc_component_read(rt5645->component, RT5645_INT_IRQ_ST) & 0x1000;
33336e747d53SBard Liao break;
33346e747d53SBard Liao
33356e747d53SBard Liao }
33366e747d53SBard Liao
33376b5da663SBard Liao if (!val && (rt5645->jack_type == 0)) { /* jack in */
333879223bf1SKuninori Morimoto report = rt5645_jack_detect(rt5645->component, 1);
33398f82f2e4SShuming Fan } else if (!val && rt5645->jack_type == SND_JACK_HEADSET) {
33406e747d53SBard Liao /* for push button and jack out */
33416e747d53SBard Liao btn_type = 0;
3342467a2553SKuninori Morimoto if (snd_soc_component_read(rt5645->component, RT5645_INT_IRQ_ST) & 0x4) {
33436e747d53SBard Liao /* button pressed */
33446e747d53SBard Liao report = SND_JACK_HEADSET;
334579223bf1SKuninori Morimoto btn_type = rt5645_button_detect(rt5645->component);
33466e747d53SBard Liao /* rt5650 can report three kinds of button behavior,
33476e747d53SBard Liao one click, double click and hold. However,
33486e747d53SBard Liao currently we will report button pressed/released
33496e747d53SBard Liao event. So all the three button behaviors are
33506e747d53SBard Liao treated as button pressed. */
33516e747d53SBard Liao switch (btn_type) {
33526e747d53SBard Liao case 0x8000:
33536e747d53SBard Liao case 0x4000:
33546e747d53SBard Liao case 0x2000:
33556e747d53SBard Liao report |= SND_JACK_BTN_0;
33566e747d53SBard Liao break;
33576e747d53SBard Liao case 0x1000:
33586e747d53SBard Liao case 0x0800:
33596e747d53SBard Liao case 0x0400:
33606e747d53SBard Liao report |= SND_JACK_BTN_1;
33616e747d53SBard Liao break;
33626e747d53SBard Liao case 0x0200:
33636e747d53SBard Liao case 0x0100:
33646e747d53SBard Liao case 0x0080:
33656e747d53SBard Liao report |= SND_JACK_BTN_2;
33666e747d53SBard Liao break;
33676e747d53SBard Liao case 0x0040:
33686e747d53SBard Liao case 0x0020:
33696e747d53SBard Liao case 0x0010:
33706e747d53SBard Liao report |= SND_JACK_BTN_3;
33716e747d53SBard Liao break;
33726e747d53SBard Liao case 0x0000: /* unpressed */
33736e747d53SBard Liao break;
33746e747d53SBard Liao default:
337579223bf1SKuninori Morimoto dev_err(rt5645->component->dev,
33766e747d53SBard Liao "Unexpected button code 0x%04x\n",
33776e747d53SBard Liao btn_type);
33786e747d53SBard Liao break;
33796e747d53SBard Liao }
33806e747d53SBard Liao }
33816e747d53SBard Liao if (btn_type == 0)/* button release */
33826e747d53SBard Liao report = rt5645->jack_type;
33837ff6319eSBard Liao else {
33847ff6319eSBard Liao mod_timer(&rt5645->btn_check_timer,
33857ff6319eSBard Liao msecs_to_jiffies(100));
33867ff6319eSBard Liao }
33876b5da663SBard Liao } else {
33886e747d53SBard Liao /* jack out */
33896e747d53SBard Liao report = 0;
339079223bf1SKuninori Morimoto snd_soc_component_update_bits(rt5645->component,
33916e747d53SBard Liao RT5645_INT_IRQ_ST, 0x1, 0x0);
339279223bf1SKuninori Morimoto rt5645_jack_detect(rt5645->component, 0);
33936e747d53SBard Liao }
33946e747d53SBard Liao
33958f82f2e4SShuming Fan mutex_unlock(&rt5645->jd_mutex);
33968f82f2e4SShuming Fan
33976e747d53SBard Liao snd_soc_jack_report(rt5645->hp_jack, report, SND_JACK_HEADPHONE);
33986e747d53SBard Liao snd_soc_jack_report(rt5645->mic_jack, report, SND_JACK_MICROPHONE);
33996e747d53SBard Liao if (rt5645->en_button_func)
34006e747d53SBard Liao snd_soc_jack_report(rt5645->btn_jack,
3401e0b5d906SBard Liao report, SND_JACK_BTN_0 | SND_JACK_BTN_1 |
3402e0b5d906SBard Liao SND_JACK_BTN_2 | SND_JACK_BTN_3);
3403f312bc59SNicolas Boichat }
34046e747d53SBard Liao
rt5645_rcclock_work(struct work_struct * work)34057099ee85SOder Chiou static void rt5645_rcclock_work(struct work_struct *work)
34067099ee85SOder Chiou {
34077099ee85SOder Chiou struct rt5645_priv *rt5645 =
34087099ee85SOder Chiou container_of(work, struct rt5645_priv, rcclock_work.work);
34097099ee85SOder Chiou
34107099ee85SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_MICBIAS,
34117099ee85SOder Chiou RT5645_PWR_CLK25M_MASK, RT5645_PWR_CLK25M_PD);
34127099ee85SOder Chiou }
34137099ee85SOder Chiou
rt5645_irq(int irq,void * data)3414f312bc59SNicolas Boichat static irqreturn_t rt5645_irq(int irq, void *data)
3415f312bc59SNicolas Boichat {
3416f312bc59SNicolas Boichat struct rt5645_priv *rt5645 = data;
3417f312bc59SNicolas Boichat
3418f312bc59SNicolas Boichat queue_delayed_work(system_power_efficient_wq,
3419f312bc59SNicolas Boichat &rt5645->jack_detect_work, msecs_to_jiffies(250));
3420f312bc59SNicolas Boichat
3421f312bc59SNicolas Boichat return IRQ_HANDLED;
34226e747d53SBard Liao }
34236e747d53SBard Liao
rt5645_btn_check_callback(struct timer_list * t)34247211ec63SKees Cook static void rt5645_btn_check_callback(struct timer_list *t)
34257ff6319eSBard Liao {
34267211ec63SKees Cook struct rt5645_priv *rt5645 = from_timer(rt5645, t, btn_check_timer);
34277ff6319eSBard Liao
34287ff6319eSBard Liao queue_delayed_work(system_power_efficient_wq,
34297ff6319eSBard Liao &rt5645->jack_detect_work, msecs_to_jiffies(5));
34307ff6319eSBard Liao }
34317ff6319eSBard Liao
rt5645_probe(struct snd_soc_component * component)343279223bf1SKuninori Morimoto static int rt5645_probe(struct snd_soc_component *component)
34331319b2f6SOder Chiou {
343479223bf1SKuninori Morimoto struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
343579223bf1SKuninori Morimoto struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
34361319b2f6SOder Chiou
343779223bf1SKuninori Morimoto rt5645->component = component;
34381319b2f6SOder Chiou
34395c4ca99dSBard Liao switch (rt5645->codec_type) {
34405c4ca99dSBard Liao case CODEC_TYPE_RT5645:
344110043bb6SMark Brown snd_soc_dapm_new_controls(dapm,
344283c09290SBard Liao rt5645_specific_dapm_widgets,
344383c09290SBard Liao ARRAY_SIZE(rt5645_specific_dapm_widgets));
344410043bb6SMark Brown snd_soc_dapm_add_routes(dapm,
34455c4ca99dSBard Liao rt5645_specific_dapm_routes,
34465c4ca99dSBard Liao ARRAY_SIZE(rt5645_specific_dapm_routes));
344750f510a3SBard Liao if (rt5645->v_id < 3) {
344810043bb6SMark Brown snd_soc_dapm_add_routes(dapm,
344950f510a3SBard Liao rt5645_old_dapm_routes,
345050f510a3SBard Liao ARRAY_SIZE(rt5645_old_dapm_routes));
345150f510a3SBard Liao }
34525c4ca99dSBard Liao break;
34535c4ca99dSBard Liao case CODEC_TYPE_RT5650:
345410043bb6SMark Brown snd_soc_dapm_new_controls(dapm,
34555c4ca99dSBard Liao rt5650_specific_dapm_widgets,
34565c4ca99dSBard Liao ARRAY_SIZE(rt5650_specific_dapm_widgets));
345710043bb6SMark Brown snd_soc_dapm_add_routes(dapm,
34585c4ca99dSBard Liao rt5650_specific_dapm_routes,
34595c4ca99dSBard Liao ARRAY_SIZE(rt5650_specific_dapm_routes));
34605c4ca99dSBard Liao break;
34615c4ca99dSBard Liao }
34625c4ca99dSBard Liao
346379223bf1SKuninori Morimoto snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF);
34641319b2f6SOder Chiou
3465bb656addSBard Liao /* for JD function */
3466ac4fc3eeSBard Liao if (rt5645->pdata.jd_mode) {
346710043bb6SMark Brown snd_soc_dapm_force_enable_pin(dapm, "JD Power");
346810043bb6SMark Brown snd_soc_dapm_force_enable_pin(dapm, "LDO2");
346910043bb6SMark Brown snd_soc_dapm_sync(dapm);
3470bb656addSBard Liao }
3471bb656addSBard Liao
3472aa9c387cSHans de Goede if (rt5645->pdata.long_name)
347379223bf1SKuninori Morimoto component->card->long_name = rt5645->pdata.long_name;
3474aa9c387cSHans de Goede
3475a86854d0SKees Cook rt5645->eq_param = devm_kcalloc(component->dev,
3476a86854d0SKees Cook RT5645_HWEQ_NUM, sizeof(struct rt5645_eq_param_s),
3477a86854d0SKees Cook GFP_KERNEL);
3478be77b38aSOder Chiou
34795e70b8e2SPhillip Potter if (!rt5645->eq_param)
348010043bb6SMark Brown return -ENOMEM;
348110043bb6SMark Brown
348210043bb6SMark Brown return 0;
34831319b2f6SOder Chiou }
34841319b2f6SOder Chiou
rt5645_remove(struct snd_soc_component * component)348579223bf1SKuninori Morimoto static void rt5645_remove(struct snd_soc_component *component)
34861319b2f6SOder Chiou {
348779223bf1SKuninori Morimoto rt5645_reset(component);
34881319b2f6SOder Chiou }
34891319b2f6SOder Chiou
34901319b2f6SOder Chiou #ifdef CONFIG_PM
rt5645_suspend(struct snd_soc_component * component)349179223bf1SKuninori Morimoto static int rt5645_suspend(struct snd_soc_component *component)
34921319b2f6SOder Chiou {
349379223bf1SKuninori Morimoto struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
34941319b2f6SOder Chiou
34951319b2f6SOder Chiou regcache_cache_only(rt5645->regmap, true);
34961319b2f6SOder Chiou regcache_mark_dirty(rt5645->regmap);
34971319b2f6SOder Chiou
34981319b2f6SOder Chiou return 0;
34991319b2f6SOder Chiou }
35001319b2f6SOder Chiou
rt5645_resume(struct snd_soc_component * component)350179223bf1SKuninori Morimoto static int rt5645_resume(struct snd_soc_component *component)
35021319b2f6SOder Chiou {
350379223bf1SKuninori Morimoto struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
35041319b2f6SOder Chiou
35051319b2f6SOder Chiou regcache_cache_only(rt5645->regmap, false);
35060f776efdSOder Chiou regcache_sync(rt5645->regmap);
35071319b2f6SOder Chiou
35081319b2f6SOder Chiou return 0;
35091319b2f6SOder Chiou }
35101319b2f6SOder Chiou #else
35111319b2f6SOder Chiou #define rt5645_suspend NULL
35121319b2f6SOder Chiou #define rt5645_resume NULL
35131319b2f6SOder Chiou #endif
35141319b2f6SOder Chiou
35151319b2f6SOder Chiou #define RT5645_STEREO_RATES SNDRV_PCM_RATE_8000_96000
35161319b2f6SOder Chiou #define RT5645_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
35171319b2f6SOder Chiou SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
35181319b2f6SOder Chiou
351964793047SAxel Lin static const struct snd_soc_dai_ops rt5645_aif_dai_ops = {
35201319b2f6SOder Chiou .hw_params = rt5645_hw_params,
35211319b2f6SOder Chiou .set_fmt = rt5645_set_dai_fmt,
35221319b2f6SOder Chiou .set_sysclk = rt5645_set_dai_sysclk,
35231319b2f6SOder Chiou .set_tdm_slot = rt5645_set_tdm_slot,
35241319b2f6SOder Chiou .set_pll = rt5645_set_dai_pll,
35251319b2f6SOder Chiou };
35261319b2f6SOder Chiou
35279e22f782SOder Chiou static struct snd_soc_dai_driver rt5645_dai[] = {
35281319b2f6SOder Chiou {
35291319b2f6SOder Chiou .name = "rt5645-aif1",
35301319b2f6SOder Chiou .id = RT5645_AIF1,
35311319b2f6SOder Chiou .playback = {
35321319b2f6SOder Chiou .stream_name = "AIF1 Playback",
35331319b2f6SOder Chiou .channels_min = 1,
35341319b2f6SOder Chiou .channels_max = 2,
35351319b2f6SOder Chiou .rates = RT5645_STEREO_RATES,
35361319b2f6SOder Chiou .formats = RT5645_FORMATS,
35371319b2f6SOder Chiou },
35381319b2f6SOder Chiou .capture = {
35391319b2f6SOder Chiou .stream_name = "AIF1 Capture",
35401319b2f6SOder Chiou .channels_min = 1,
3541fbe039bbSBen Zhang .channels_max = 4,
35421319b2f6SOder Chiou .rates = RT5645_STEREO_RATES,
35431319b2f6SOder Chiou .formats = RT5645_FORMATS,
35441319b2f6SOder Chiou },
35451319b2f6SOder Chiou .ops = &rt5645_aif_dai_ops,
35461319b2f6SOder Chiou },
35471319b2f6SOder Chiou {
35481319b2f6SOder Chiou .name = "rt5645-aif2",
35491319b2f6SOder Chiou .id = RT5645_AIF2,
35501319b2f6SOder Chiou .playback = {
35511319b2f6SOder Chiou .stream_name = "AIF2 Playback",
35521319b2f6SOder Chiou .channels_min = 1,
35531319b2f6SOder Chiou .channels_max = 2,
35541319b2f6SOder Chiou .rates = RT5645_STEREO_RATES,
35551319b2f6SOder Chiou .formats = RT5645_FORMATS,
35561319b2f6SOder Chiou },
35571319b2f6SOder Chiou .capture = {
35581319b2f6SOder Chiou .stream_name = "AIF2 Capture",
35591319b2f6SOder Chiou .channels_min = 1,
35601319b2f6SOder Chiou .channels_max = 2,
35611319b2f6SOder Chiou .rates = RT5645_STEREO_RATES,
35621319b2f6SOder Chiou .formats = RT5645_FORMATS,
35631319b2f6SOder Chiou },
35641319b2f6SOder Chiou .ops = &rt5645_aif_dai_ops,
35651319b2f6SOder Chiou },
35661319b2f6SOder Chiou };
35671319b2f6SOder Chiou
356879223bf1SKuninori Morimoto static const struct snd_soc_component_driver soc_component_dev_rt5645 = {
35691319b2f6SOder Chiou .probe = rt5645_probe,
35701319b2f6SOder Chiou .remove = rt5645_remove,
35711319b2f6SOder Chiou .suspend = rt5645_suspend,
35721319b2f6SOder Chiou .resume = rt5645_resume,
35731319b2f6SOder Chiou .set_bias_level = rt5645_set_bias_level,
35741319b2f6SOder Chiou .controls = rt5645_snd_controls,
35751319b2f6SOder Chiou .num_controls = ARRAY_SIZE(rt5645_snd_controls),
35761319b2f6SOder Chiou .dapm_widgets = rt5645_dapm_widgets,
35771319b2f6SOder Chiou .num_dapm_widgets = ARRAY_SIZE(rt5645_dapm_widgets),
35781319b2f6SOder Chiou .dapm_routes = rt5645_dapm_routes,
35791319b2f6SOder Chiou .num_dapm_routes = ARRAY_SIZE(rt5645_dapm_routes),
35807f6ecc22SShuming Fan .set_jack = rt5645_component_set_jack,
358179223bf1SKuninori Morimoto .use_pmdown_time = 1,
358279223bf1SKuninori Morimoto .endianness = 1,
35831319b2f6SOder Chiou };
35841319b2f6SOder Chiou
35851319b2f6SOder Chiou static const struct regmap_config rt5645_regmap = {
35861319b2f6SOder Chiou .reg_bits = 8,
35871319b2f6SOder Chiou .val_bits = 16,
35881c96a2f6SDavid Frey .use_single_read = true,
35891c96a2f6SDavid Frey .use_single_write = true,
35901319b2f6SOder Chiou .max_register = RT5645_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5645_ranges) *
35911319b2f6SOder Chiou RT5645_PR_SPACING),
35921319b2f6SOder Chiou .volatile_reg = rt5645_volatile_register,
35931319b2f6SOder Chiou .readable_reg = rt5645_readable_register,
35941319b2f6SOder Chiou
3595ea3945cdSMark Brown .cache_type = REGCACHE_MAPLE,
35961319b2f6SOder Chiou .reg_defaults = rt5645_reg,
35971319b2f6SOder Chiou .num_reg_defaults = ARRAY_SIZE(rt5645_reg),
35981319b2f6SOder Chiou .ranges = rt5645_ranges,
35991319b2f6SOder Chiou .num_ranges = ARRAY_SIZE(rt5645_ranges),
36001319b2f6SOder Chiou };
36011319b2f6SOder Chiou
360249abc6cdSBard Liao static const struct regmap_config rt5650_regmap = {
360349abc6cdSBard Liao .reg_bits = 8,
360449abc6cdSBard Liao .val_bits = 16,
36051c96a2f6SDavid Frey .use_single_read = true,
36061c96a2f6SDavid Frey .use_single_write = true,
360749abc6cdSBard Liao .max_register = RT5645_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5645_ranges) *
360849abc6cdSBard Liao RT5645_PR_SPACING),
360949abc6cdSBard Liao .volatile_reg = rt5645_volatile_register,
361049abc6cdSBard Liao .readable_reg = rt5645_readable_register,
361149abc6cdSBard Liao
3612ea3945cdSMark Brown .cache_type = REGCACHE_MAPLE,
361349abc6cdSBard Liao .reg_defaults = rt5650_reg,
361449abc6cdSBard Liao .num_reg_defaults = ARRAY_SIZE(rt5650_reg),
361549abc6cdSBard Liao .ranges = rt5645_ranges,
361649abc6cdSBard Liao .num_ranges = ARRAY_SIZE(rt5645_ranges),
361749abc6cdSBard Liao };
361849abc6cdSBard Liao
361949abc6cdSBard Liao static const struct regmap_config temp_regmap = {
362049abc6cdSBard Liao .name="nocache",
362149abc6cdSBard Liao .reg_bits = 8,
362249abc6cdSBard Liao .val_bits = 16,
36231c96a2f6SDavid Frey .use_single_read = true,
36241c96a2f6SDavid Frey .use_single_write = true,
362549abc6cdSBard Liao .max_register = RT5645_VENDOR_ID2 + 1,
362649abc6cdSBard Liao .cache_type = REGCACHE_NONE,
362749abc6cdSBard Liao };
362849abc6cdSBard Liao
36291319b2f6SOder Chiou static const struct i2c_device_id rt5645_i2c_id[] = {
36301319b2f6SOder Chiou { "rt5645", 0 },
36315c4ca99dSBard Liao { "rt5650", 0 },
36321319b2f6SOder Chiou { }
36331319b2f6SOder Chiou };
36341319b2f6SOder Chiou MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id);
36351319b2f6SOder Chiou
36369ba2da5fSJavier Martinez Canillas #ifdef CONFIG_OF
36379ba2da5fSJavier Martinez Canillas static const struct of_device_id rt5645_of_match[] = {
36389ba2da5fSJavier Martinez Canillas { .compatible = "realtek,rt5645", },
36399ba2da5fSJavier Martinez Canillas { .compatible = "realtek,rt5650", },
36409ba2da5fSJavier Martinez Canillas { }
36419ba2da5fSJavier Martinez Canillas };
36429ba2da5fSJavier Martinez Canillas MODULE_DEVICE_TABLE(of, rt5645_of_match);
36439ba2da5fSJavier Martinez Canillas #endif
36449ba2da5fSJavier Martinez Canillas
36453168c201SFang, Yang A #ifdef CONFIG_ACPI
3646e2973769SMathias Krause static const struct acpi_device_id rt5645_acpi_match[] = {
36473168c201SFang, Yang A { "10EC5645", 0 },
364811ad8089SPierre-Louis Bossart { "10EC5648", 0 },
36493168c201SFang, Yang A { "10EC5650", 0 },
365079c89031SVinod Koul { "10EC5640", 0 },
3651ff9d1fbbSPierre-Louis Bossart { "10EC3270", 0 },
36523168c201SFang, Yang A {},
36533168c201SFang, Yang A };
36543168c201SFang, Yang A MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match);
36553168c201SFang, Yang A #endif
36563168c201SFang, Yang A
365778f5605cSHans de Goede static const struct rt5645_platform_data intel_braswell_platform_data = {
3658ac4fc3eeSBard Liao .dmic1_data_pin = RT5645_DMIC1_DISABLE,
365978c34fd4SFang, Yang A .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
366078c34fd4SFang, Yang A .jd_mode = 3,
366178c34fd4SFang, Yang A };
366278c34fd4SFang, Yang A
3663cd6d6477SBhumika Goyal static const struct rt5645_platform_data buddy_platform_data = {
3664e9159e75SJohn Lin .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5,
3665e9159e75SJohn Lin .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
3666e7cfd867SJacob Rasmussen .jd_mode = 4,
366789575022SBard Liao .level_trigger_irq = true,
3668e9159e75SJohn Lin };
3669e9159e75SJohn Lin
3670cd6d6477SBhumika Goyal static const struct rt5645_platform_data gpd_win_platform_data = {
3671ea2b5a6eSTakashi Iwai .jd_mode = 3,
3672ea2b5a6eSTakashi Iwai .inv_jd1_1 = true,
3673aa9c387cSHans de Goede .long_name = "gpd-win-pocket-rt5645",
36742dc6e1a4SHans de Goede /* The GPD pocket has a diff. mic, for the win this does not matter. */
36752dc6e1a4SHans de Goede .in2_diff = true,
3676ea2b5a6eSTakashi Iwai };
3677ea2b5a6eSTakashi Iwai
367878f5605cSHans de Goede static const struct rt5645_platform_data asus_t100ha_platform_data = {
367978f5605cSHans de Goede .dmic1_data_pin = RT5645_DMIC_DATA_IN2N,
368078f5605cSHans de Goede .dmic2_data_pin = RT5645_DMIC2_DISABLE,
368178f5605cSHans de Goede .jd_mode = 3,
368278f5605cSHans de Goede .inv_jd1_1 = true,
368378f5605cSHans de Goede };
368478f5605cSHans de Goede
368579d4f823SHans de Goede static const struct rt5645_platform_data asus_t101ha_platform_data = {
368679d4f823SHans de Goede .dmic1_data_pin = RT5645_DMIC_DATA_IN2N,
368779d4f823SHans de Goede .dmic2_data_pin = RT5645_DMIC2_DISABLE,
368879d4f823SHans de Goede .jd_mode = 3,
368979d4f823SHans de Goede };
369079d4f823SHans de Goede
369187927581SHans de Goede static const struct rt5645_platform_data lenovo_ideapad_miix_310_pdata = {
369287927581SHans de Goede .jd_mode = 3,
369387927581SHans de Goede .in2_diff = true,
369487927581SHans de Goede };
369587927581SHans de Goede
369678f5605cSHans de Goede static const struct rt5645_platform_data jd_mode3_platform_data = {
369778f5605cSHans de Goede .jd_mode = 3,
369878f5605cSHans de Goede };
369978f5605cSHans de Goede
3700406dcbc5SHui Wang static const struct rt5645_platform_data lattepanda_board_platform_data = {
3701406dcbc5SHui Wang .jd_mode = 2,
3702406dcbc5SHui Wang .inv_jd1_1 = true
3703406dcbc5SHui Wang };
3704406dcbc5SHui Wang
3705e42599d6SAkshu Agrawal static const struct rt5645_platform_data kahlee_platform_data = {
3706e42599d6SAkshu Agrawal .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5,
3707e42599d6SAkshu Agrawal .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
3708e42599d6SAkshu Agrawal .jd_mode = 3,
3709e42599d6SAkshu Agrawal };
3710e42599d6SAkshu Agrawal
37113ac2bfd5SChris Chiu static const struct rt5645_platform_data ecs_ef20_platform_data = {
37123ac2bfd5SChris Chiu .dmic1_data_pin = RT5645_DMIC1_DISABLE,
37133ac2bfd5SChris Chiu .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
37143ac2bfd5SChris Chiu .inv_hp_pol = 1,
37153ac2bfd5SChris Chiu };
37163ac2bfd5SChris Chiu
3717a4dae468SChris Chiu static const struct acpi_gpio_params ef20_hp_detect = { 1, 0, false };
3718a4dae468SChris Chiu
3719a4dae468SChris Chiu static const struct acpi_gpio_mapping cht_rt5645_ef20_gpios[] = {
3720a4dae468SChris Chiu { "hp-detect-gpios", &ef20_hp_detect, 1 },
3721a4dae468SChris Chiu { },
3722a4dae468SChris Chiu };
3723a4dae468SChris Chiu
cht_rt5645_ef20_quirk_cb(const struct dmi_system_id * id)3724a4dae468SChris Chiu static int cht_rt5645_ef20_quirk_cb(const struct dmi_system_id *id)
3725a4dae468SChris Chiu {
3726a4dae468SChris Chiu cht_rt5645_gpios = cht_rt5645_ef20_gpios;
3727a4dae468SChris Chiu return 1;
3728a4dae468SChris Chiu }
3729a4dae468SChris Chiu
373078f5605cSHans de Goede static const struct dmi_system_id dmi_platform_data[] = {
3731e9159e75SJohn Lin {
3732e9159e75SJohn Lin .ident = "Chrome Buddy",
3733e9159e75SJohn Lin .matches = {
3734e9159e75SJohn Lin DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"),
3735e9159e75SJohn Lin },
373678f5605cSHans de Goede .driver_data = (void *)&buddy_platform_data,
3737e9159e75SJohn Lin },
373878f5605cSHans de Goede {
373978f5605cSHans de Goede .ident = "Intel Strago",
374078f5605cSHans de Goede .matches = {
374178f5605cSHans de Goede DMI_MATCH(DMI_PRODUCT_NAME, "Strago"),
374278f5605cSHans de Goede },
374378f5605cSHans de Goede .driver_data = (void *)&intel_braswell_platform_data,
374478f5605cSHans de Goede },
374578f5605cSHans de Goede {
374678f5605cSHans de Goede .ident = "Google Chrome",
374778f5605cSHans de Goede .matches = {
374878f5605cSHans de Goede DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
374978f5605cSHans de Goede },
375078f5605cSHans de Goede .driver_data = (void *)&intel_braswell_platform_data,
375178f5605cSHans de Goede },
375278f5605cSHans de Goede {
375378f5605cSHans de Goede .ident = "Google Setzer",
375478f5605cSHans de Goede .matches = {
375578f5605cSHans de Goede DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"),
375678f5605cSHans de Goede },
375778f5605cSHans de Goede .driver_data = (void *)&intel_braswell_platform_data,
375878f5605cSHans de Goede },
375978f5605cSHans de Goede {
376078f5605cSHans de Goede .ident = "Microsoft Surface 3",
376178f5605cSHans de Goede .matches = {
376278f5605cSHans de Goede DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"),
376378f5605cSHans de Goede },
376478f5605cSHans de Goede .driver_data = (void *)&intel_braswell_platform_data,
376578f5605cSHans de Goede },
3766ea2b5a6eSTakashi Iwai {
3767ea2b5a6eSTakashi Iwai /*
3768ea2b5a6eSTakashi Iwai * Match for the GPDwin which unfortunately uses somewhat
3769ea2b5a6eSTakashi Iwai * generic dmi strings, which is why we test for 4 strings.
3770ea2b5a6eSTakashi Iwai * Comparing against 23 other byt/cht boards, board_vendor
3771ea2b5a6eSTakashi Iwai * and board_name are unique to the GPDwin, where as only one
3772ea2b5a6eSTakashi Iwai * other board has the same board_serial and 3 others have
3773ea2b5a6eSTakashi Iwai * the same default product_name. Also the GPDwin is the
3774ea2b5a6eSTakashi Iwai * only device to have both board_ and product_name not set.
3775ea2b5a6eSTakashi Iwai */
377678f5605cSHans de Goede .ident = "GPD Win / Pocket",
3777ea2b5a6eSTakashi Iwai .matches = {
3778ea2b5a6eSTakashi Iwai DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
3779ea2b5a6eSTakashi Iwai DMI_MATCH(DMI_BOARD_NAME, "Default string"),
3780ea2b5a6eSTakashi Iwai DMI_MATCH(DMI_BOARD_SERIAL, "Default string"),
3781ea2b5a6eSTakashi Iwai DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
3782ea2b5a6eSTakashi Iwai },
378378f5605cSHans de Goede .driver_data = (void *)&gpd_win_platform_data,
3784ea2b5a6eSTakashi Iwai },
3785cb0236ecSPierre-Louis Bossart {
3786cb0236ecSPierre-Louis Bossart .ident = "ASUS T100HAN",
3787cb0236ecSPierre-Louis Bossart .matches = {
3788cb0236ecSPierre-Louis Bossart DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
3789cb0236ecSPierre-Louis Bossart DMI_MATCH(DMI_PRODUCT_NAME, "T100HAN"),
3790cb0236ecSPierre-Louis Bossart },
379178f5605cSHans de Goede .driver_data = (void *)&asus_t100ha_platform_data,
3792cb0236ecSPierre-Louis Bossart },
379388faae2cSIan W MORRISON {
379479d4f823SHans de Goede .ident = "ASUS T101HA",
379579d4f823SHans de Goede .matches = {
379679d4f823SHans de Goede DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
379779d4f823SHans de Goede DMI_MATCH(DMI_PRODUCT_NAME, "T101HA"),
379879d4f823SHans de Goede },
379979d4f823SHans de Goede .driver_data = (void *)&asus_t101ha_platform_data,
380079d4f823SHans de Goede },
380179d4f823SHans de Goede {
380288faae2cSIan W MORRISON .ident = "MINIX Z83-4",
380388faae2cSIan W MORRISON .matches = {
380488faae2cSIan W MORRISON DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MINIX"),
380588faae2cSIan W MORRISON DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"),
380688faae2cSIan W MORRISON },
380778f5605cSHans de Goede .driver_data = (void *)&jd_mode3_platform_data,
380888faae2cSIan W MORRISON },
3809a249a956SHans de Goede {
3810a249a956SHans de Goede .ident = "Teclast X80 Pro",
3811a249a956SHans de Goede .matches = {
3812a249a956SHans de Goede DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
3813a249a956SHans de Goede DMI_MATCH(DMI_PRODUCT_NAME, "X80 Pro"),
3814a249a956SHans de Goede },
3815a249a956SHans de Goede .driver_data = (void *)&jd_mode3_platform_data,
381688faae2cSIan W MORRISON },
381787927581SHans de Goede {
381887927581SHans de Goede .ident = "Lenovo Ideapad Miix 310",
381987927581SHans de Goede .matches = {
382087927581SHans de Goede DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
382187927581SHans de Goede DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80SG"),
382287927581SHans de Goede DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "MIIX 310-10ICR"),
382387927581SHans de Goede },
382487927581SHans de Goede .driver_data = (void *)&lenovo_ideapad_miix_310_pdata,
382587927581SHans de Goede },
382625c8b550SHans de Goede {
382725c8b550SHans de Goede .ident = "Lenovo Ideapad Miix 320",
382825c8b550SHans de Goede .matches = {
382925c8b550SHans de Goede DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
383025c8b550SHans de Goede DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "80XF"),
383125c8b550SHans de Goede DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"),
383225c8b550SHans de Goede },
383325c8b550SHans de Goede .driver_data = (void *)&intel_braswell_platform_data,
383425c8b550SHans de Goede },
3835406dcbc5SHui Wang {
3836406dcbc5SHui Wang .ident = "LattePanda board",
3837406dcbc5SHui Wang .matches = {
3838406dcbc5SHui Wang DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
3839406dcbc5SHui Wang DMI_EXACT_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
3840406dcbc5SHui Wang DMI_EXACT_MATCH(DMI_BOARD_VERSION, "Default string"),
3841c33afbccSHans de Goede /*
3842c33afbccSHans de Goede * Above strings are too generic, LattePanda BIOS versions for
3843c33afbccSHans de Goede * all 4 hw revisions are:
3844c33afbccSHans de Goede * DF-BI-7-S70CR100-*
3845c33afbccSHans de Goede * DF-BI-7-S70CR110-*
3846c33afbccSHans de Goede * DF-BI-7-S70CR200-*
3847c33afbccSHans de Goede * LP-BS-7-S70CR700-*
3848c33afbccSHans de Goede * Do a partial match for S70CR to avoid false positive matches.
3849c33afbccSHans de Goede */
3850c33afbccSHans de Goede DMI_MATCH(DMI_BIOS_VERSION, "S70CR"),
3851406dcbc5SHui Wang },
3852406dcbc5SHui Wang .driver_data = (void *)&lattepanda_board_platform_data,
3853406dcbc5SHui Wang },
3854e42599d6SAkshu Agrawal {
3855e42599d6SAkshu Agrawal .ident = "Chrome Kahlee",
3856e42599d6SAkshu Agrawal .matches = {
3857e42599d6SAkshu Agrawal DMI_MATCH(DMI_PRODUCT_NAME, "Kahlee"),
3858e42599d6SAkshu Agrawal },
3859e42599d6SAkshu Agrawal .driver_data = (void *)&kahlee_platform_data,
3860e42599d6SAkshu Agrawal },
38614146575eSHans de Goede {
38624146575eSHans de Goede .ident = "Medion E1239T",
38634146575eSHans de Goede .matches = {
38644146575eSHans de Goede DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MEDION"),
38654146575eSHans de Goede DMI_MATCH(DMI_PRODUCT_NAME, "E1239T MD60568"),
38664146575eSHans de Goede },
38674146575eSHans de Goede .driver_data = (void *)&intel_braswell_platform_data,
38684146575eSHans de Goede },
3869a4dae468SChris Chiu {
3870a4dae468SChris Chiu .ident = "EF20",
3871a4dae468SChris Chiu .callback = cht_rt5645_ef20_quirk_cb,
3872a4dae468SChris Chiu .matches = {
3873a4dae468SChris Chiu DMI_MATCH(DMI_PRODUCT_NAME, "EF20"),
3874a4dae468SChris Chiu },
38753ac2bfd5SChris Chiu .driver_data = (void *)&ecs_ef20_platform_data,
3876a4dae468SChris Chiu },
387788faae2cSIan W MORRISON { }
387888faae2cSIan W MORRISON };
387988faae2cSIan W MORRISON
rt5645_check_dp(struct device * dev)38809761c0f6SBard Liao static bool rt5645_check_dp(struct device *dev)
38819761c0f6SBard Liao {
38829761c0f6SBard Liao if (device_property_present(dev, "realtek,in2-differential") ||
38839761c0f6SBard Liao device_property_present(dev, "realtek,dmic1-data-pin") ||
38849761c0f6SBard Liao device_property_present(dev, "realtek,dmic2-data-pin") ||
38859761c0f6SBard Liao device_property_present(dev, "realtek,jd-mode"))
38869761c0f6SBard Liao return true;
38879761c0f6SBard Liao
38889761c0f6SBard Liao return false;
38899761c0f6SBard Liao }
3890e9159e75SJohn Lin
rt5645_parse_dt(struct rt5645_priv * rt5645,struct device * dev)389148edaa4bSOder Chiou static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev)
389248edaa4bSOder Chiou {
389348edaa4bSOder Chiou rt5645->pdata.in2_diff = device_property_read_bool(dev,
389448edaa4bSOder Chiou "realtek,in2-differential");
389548edaa4bSOder Chiou device_property_read_u32(dev,
389648edaa4bSOder Chiou "realtek,dmic1-data-pin", &rt5645->pdata.dmic1_data_pin);
389748edaa4bSOder Chiou device_property_read_u32(dev,
389848edaa4bSOder Chiou "realtek,dmic2-data-pin", &rt5645->pdata.dmic2_data_pin);
389948edaa4bSOder Chiou device_property_read_u32(dev,
390048edaa4bSOder Chiou "realtek,jd-mode", &rt5645->pdata.jd_mode);
390148edaa4bSOder Chiou
390248edaa4bSOder Chiou return 0;
390348edaa4bSOder Chiou }
390448edaa4bSOder Chiou
rt5645_i2c_probe(struct i2c_client * i2c)390535b88858SStephen Kitt static int rt5645_i2c_probe(struct i2c_client *i2c)
39061319b2f6SOder Chiou {
3907452801caSHans de Goede struct rt5645_platform_data *pdata = NULL;
390878f5605cSHans de Goede const struct dmi_system_id *dmi_data;
39091319b2f6SOder Chiou struct rt5645_priv *rt5645;
39109fc114c5SKoro Chen int ret, i;
39111319b2f6SOder Chiou unsigned int val;
391249abc6cdSBard Liao struct regmap *regmap;
39131319b2f6SOder Chiou
39141319b2f6SOder Chiou rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv),
39151319b2f6SOder Chiou GFP_KERNEL);
39161319b2f6SOder Chiou if (rt5645 == NULL)
39171319b2f6SOder Chiou return -ENOMEM;
39181319b2f6SOder Chiou
3919f3fa1bbdSOder Chiou rt5645->i2c = i2c;
39201319b2f6SOder Chiou i2c_set_clientdata(i2c, rt5645);
39211319b2f6SOder Chiou
392278f5605cSHans de Goede dmi_data = dmi_first_match(dmi_platform_data);
392378f5605cSHans de Goede if (dmi_data) {
392478f5605cSHans de Goede dev_info(&i2c->dev, "Detected %s platform\n", dmi_data->ident);
392578f5605cSHans de Goede pdata = dmi_data->driver_data;
392678f5605cSHans de Goede }
392778f5605cSHans de Goede
392848edaa4bSOder Chiou if (pdata)
39291319b2f6SOder Chiou rt5645->pdata = *pdata;
39309761c0f6SBard Liao else if (rt5645_check_dp(&i2c->dev))
393148edaa4bSOder Chiou rt5645_parse_dt(rt5645, &i2c->dev);
39325954c4a1SPierre-Louis Bossart else
39335954c4a1SPierre-Louis Bossart rt5645->pdata = jd_mode3_platform_data;
393478c34fd4SFang, Yang A
39354999b021STakashi Iwai if (quirk != -1) {
39364999b021STakashi Iwai rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk);
39374999b021STakashi Iwai rt5645->pdata.level_trigger_irq = QUIRK_LEVEL_IRQ(quirk);
39384999b021STakashi Iwai rt5645->pdata.inv_jd1_1 = QUIRK_INV_JD1_1(quirk);
393928c98849SChris Chiu rt5645->pdata.inv_hp_pol = QUIRK_INV_HP_POL(quirk);
39404999b021STakashi Iwai rt5645->pdata.jd_mode = QUIRK_JD_MODE(quirk);
39414999b021STakashi Iwai rt5645->pdata.dmic1_data_pin = QUIRK_DMIC1_DATA_PIN(quirk);
39424999b021STakashi Iwai rt5645->pdata.dmic2_data_pin = QUIRK_DMIC2_DATA_PIN(quirk);
39434999b021STakashi Iwai }
394478c34fd4SFang, Yang A
39453f004d2dSHans de Goede if (has_acpi_companion(&i2c->dev)) {
39463f004d2dSHans de Goede if (cht_rt5645_gpios) {
394721f60348SChris Chiu if (devm_acpi_dev_add_driver_gpios(&i2c->dev, cht_rt5645_gpios))
394821f60348SChris Chiu dev_dbg(&i2c->dev, "Failed to add driver gpios\n");
39493f004d2dSHans de Goede }
39503f004d2dSHans de Goede
39513f004d2dSHans de Goede /* The ALC3270 package has the headset-mic pin not-connected */
39523f004d2dSHans de Goede if (acpi_dev_hid_uid_match(ACPI_COMPANION(&i2c->dev), "10EC3270", NULL))
39533f004d2dSHans de Goede rt5645->pdata.no_headset_mic = true;
39543f004d2dSHans de Goede }
395521f60348SChris Chiu
395625c8888aSAxel Lin rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect",
395725c8888aSAxel Lin GPIOD_IN);
39580b0cefc8SOder Chiou
39590b0cefc8SOder Chiou if (IS_ERR(rt5645->gpiod_hp_det)) {
3960cec55827SPierre-Louis Bossart dev_info(&i2c->dev, "failed to initialize gpiod\n");
3961cec55827SPierre-Louis Bossart ret = PTR_ERR(rt5645->gpiod_hp_det);
3962cec55827SPierre-Louis Bossart /*
3963cec55827SPierre-Louis Bossart * Continue if optional gpiod is missing, bail for all other
3964cec55827SPierre-Louis Bossart * errors, including -EPROBE_DEFER
3965cec55827SPierre-Louis Bossart */
3966cec55827SPierre-Louis Bossart if (ret != -ENOENT)
3967cec55827SPierre-Louis Bossart return ret;
396878c34fd4SFang, Yang A }
39691319b2f6SOder Chiou
3970*7904b066SDerek Fang rt5645->gpiod_cbj_sleeve = devm_gpiod_get_optional(&i2c->dev, "cbj-sleeve",
3971*7904b066SDerek Fang GPIOD_OUT_LOW);
3972*7904b066SDerek Fang
3973*7904b066SDerek Fang if (IS_ERR(rt5645->gpiod_cbj_sleeve)) {
3974*7904b066SDerek Fang ret = PTR_ERR(rt5645->gpiod_cbj_sleeve);
3975*7904b066SDerek Fang dev_info(&i2c->dev, "failed to initialize gpiod, ret=%d\n", ret);
3976*7904b066SDerek Fang if (ret != -ENOENT)
3977*7904b066SDerek Fang return ret;
3978*7904b066SDerek Fang }
3979*7904b066SDerek Fang
39809fc114c5SKoro Chen for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++)
39819fc114c5SKoro Chen rt5645->supplies[i].supply = rt5645_supply_names[i];
39829fc114c5SKoro Chen
39839fc114c5SKoro Chen ret = devm_regulator_bulk_get(&i2c->dev,
39849fc114c5SKoro Chen ARRAY_SIZE(rt5645->supplies),
39859fc114c5SKoro Chen rt5645->supplies);
39869fc114c5SKoro Chen if (ret) {
39879fc114c5SKoro Chen dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
39889fc114c5SKoro Chen return ret;
39899fc114c5SKoro Chen }
39909fc114c5SKoro Chen
39919fc114c5SKoro Chen ret = regulator_bulk_enable(ARRAY_SIZE(rt5645->supplies),
39929fc114c5SKoro Chen rt5645->supplies);
39939fc114c5SKoro Chen if (ret) {
39949fc114c5SKoro Chen dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
39959fc114c5SKoro Chen return ret;
39969fc114c5SKoro Chen }
39979fc114c5SKoro Chen
399849abc6cdSBard Liao regmap = devm_regmap_init_i2c(i2c, &temp_regmap);
399949abc6cdSBard Liao if (IS_ERR(regmap)) {
400049abc6cdSBard Liao ret = PTR_ERR(regmap);
400149abc6cdSBard Liao dev_err(&i2c->dev, "Failed to allocate temp register map: %d\n",
400249abc6cdSBard Liao ret);
40037883c193SZheyu Ma goto err_enable;
400449abc6cdSBard Liao }
40050c279a59SAkshu Agrawal
40060c279a59SAkshu Agrawal /*
40070c279a59SAkshu Agrawal * Read after 400msec, as it is the interval required between
40080c279a59SAkshu Agrawal * read and power On.
40090c279a59SAkshu Agrawal */
40100c279a59SAkshu Agrawal msleep(TIME_TO_POWER_MS);
4011bf62eec5SShuming Fan ret = regmap_read(regmap, RT5645_VENDOR_ID2, &val);
4012bf62eec5SShuming Fan if (ret < 0) {
4013bf62eec5SShuming Fan dev_err(&i2c->dev, "Failed to read: 0x%02X\n, ret = %d", RT5645_VENDOR_ID2, ret);
4014bf62eec5SShuming Fan goto err_enable;
4015bf62eec5SShuming Fan }
40165c4ca99dSBard Liao
40175c4ca99dSBard Liao switch (val) {
40185c4ca99dSBard Liao case RT5645_DEVICE_ID:
401949abc6cdSBard Liao rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5645_regmap);
40205c4ca99dSBard Liao rt5645->codec_type = CODEC_TYPE_RT5645;
40215c4ca99dSBard Liao break;
40225c4ca99dSBard Liao case RT5650_DEVICE_ID:
402349abc6cdSBard Liao rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5650_regmap);
40245c4ca99dSBard Liao rt5645->codec_type = CODEC_TYPE_RT5650;
40255c4ca99dSBard Liao break;
40265c4ca99dSBard Liao default:
40271319b2f6SOder Chiou dev_err(&i2c->dev,
40288f68e80fSJarkko Nikula "Device with ID register %#x is not rt5645 or rt5650\n",
40295c4ca99dSBard Liao val);
40309fc114c5SKoro Chen ret = -ENODEV;
40319fc114c5SKoro Chen goto err_enable;
4032d12d6c4eSJohn Lin }
4033d12d6c4eSJohn Lin
403449abc6cdSBard Liao if (IS_ERR(rt5645->regmap)) {
403549abc6cdSBard Liao ret = PTR_ERR(rt5645->regmap);
403649abc6cdSBard Liao dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
403749abc6cdSBard Liao ret);
40387883c193SZheyu Ma goto err_enable;
403949abc6cdSBard Liao }
404049abc6cdSBard Liao
40411319b2f6SOder Chiou regmap_write(rt5645->regmap, RT5645_RESET, 0);
40421319b2f6SOder Chiou
404350f510a3SBard Liao regmap_read(regmap, RT5645_VENDOR_ID, &val);
404450f510a3SBard Liao rt5645->v_id = val & 0xff;
404550f510a3SBard Liao
404656986b07SBard Liao regmap_write(rt5645->regmap, RT5645_AD_DA_MIXER, 0x8080);
404756986b07SBard Liao
4048aa98697cSShuming Fan ret = regmap_multi_reg_write(rt5645->regmap, init_list,
40491319b2f6SOder Chiou ARRAY_SIZE(init_list));
40501319b2f6SOder Chiou if (ret != 0)
40511319b2f6SOder Chiou dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret);
40521319b2f6SOder Chiou
40535c4ca99dSBard Liao if (rt5645->codec_type == CODEC_TYPE_RT5650) {
4054aa98697cSShuming Fan ret = regmap_multi_reg_write(rt5645->regmap, rt5650_init_list,
40555c4ca99dSBard Liao ARRAY_SIZE(rt5650_init_list));
40565c4ca99dSBard Liao if (ret != 0)
40575c4ca99dSBard Liao dev_warn(&i2c->dev, "Apply rt5650 patch failed: %d\n",
40585c4ca99dSBard Liao ret);
40595c4ca99dSBard Liao }
40605c4ca99dSBard Liao
4061105e56f1SBard Liao regmap_update_bits(rt5645->regmap, RT5645_CLSD_OUT_CTRL, 0xc0, 0xc0);
4062105e56f1SBard Liao
40631319b2f6SOder Chiou if (rt5645->pdata.in2_diff)
40641319b2f6SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_IN2_CTRL,
40651319b2f6SOder Chiou RT5645_IN_DF2, RT5645_IN_DF2);
40661319b2f6SOder Chiou
4067ac4fc3eeSBard Liao if (rt5645->pdata.dmic1_data_pin || rt5645->pdata.dmic2_data_pin) {
40681319b2f6SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1,
40691319b2f6SOder Chiou RT5645_GP2_PIN_MASK, RT5645_GP2_PIN_DMIC1_SCL);
4070ac4fc3eeSBard Liao }
40711319b2f6SOder Chiou switch (rt5645->pdata.dmic1_data_pin) {
40721319b2f6SOder Chiou case RT5645_DMIC_DATA_IN2N:
40731319b2f6SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1,
40741319b2f6SOder Chiou RT5645_DMIC_1_DP_MASK, RT5645_DMIC_1_DP_IN2N);
40751319b2f6SOder Chiou break;
40761319b2f6SOder Chiou
40771319b2f6SOder Chiou case RT5645_DMIC_DATA_GPIO5:
4078a094935eSBard Liao regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1,
4079a094935eSBard Liao RT5645_I2S2_DAC_PIN_MASK, RT5645_I2S2_DAC_PIN_GPIO);
40801319b2f6SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1,
40811319b2f6SOder Chiou RT5645_DMIC_1_DP_MASK, RT5645_DMIC_1_DP_GPIO5);
40821319b2f6SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1,
40831319b2f6SOder Chiou RT5645_GP5_PIN_MASK, RT5645_GP5_PIN_DMIC1_SDA);
40841319b2f6SOder Chiou break;
40851319b2f6SOder Chiou
40861319b2f6SOder Chiou case RT5645_DMIC_DATA_GPIO11:
40871319b2f6SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1,
40881319b2f6SOder Chiou RT5645_DMIC_1_DP_MASK, RT5645_DMIC_1_DP_GPIO11);
40891319b2f6SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1,
40901319b2f6SOder Chiou RT5645_GP11_PIN_MASK,
40911319b2f6SOder Chiou RT5645_GP11_PIN_DMIC1_SDA);
40921319b2f6SOder Chiou break;
40931319b2f6SOder Chiou
40941319b2f6SOder Chiou default:
40951319b2f6SOder Chiou break;
40961319b2f6SOder Chiou }
40971319b2f6SOder Chiou
40981319b2f6SOder Chiou switch (rt5645->pdata.dmic2_data_pin) {
40991319b2f6SOder Chiou case RT5645_DMIC_DATA_IN2P:
41001319b2f6SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1,
41011319b2f6SOder Chiou RT5645_DMIC_2_DP_MASK, RT5645_DMIC_2_DP_IN2P);
41021319b2f6SOder Chiou break;
41031319b2f6SOder Chiou
41041319b2f6SOder Chiou case RT5645_DMIC_DATA_GPIO6:
41051319b2f6SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1,
41061319b2f6SOder Chiou RT5645_DMIC_2_DP_MASK, RT5645_DMIC_2_DP_GPIO6);
41071319b2f6SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1,
41081319b2f6SOder Chiou RT5645_GP6_PIN_MASK, RT5645_GP6_PIN_DMIC2_SDA);
41091319b2f6SOder Chiou break;
41101319b2f6SOder Chiou
41111319b2f6SOder Chiou case RT5645_DMIC_DATA_GPIO10:
41121319b2f6SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1,
41131319b2f6SOder Chiou RT5645_DMIC_2_DP_MASK, RT5645_DMIC_2_DP_GPIO10);
41141319b2f6SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1,
41151319b2f6SOder Chiou RT5645_GP10_PIN_MASK,
41161319b2f6SOder Chiou RT5645_GP10_PIN_DMIC2_SDA);
41171319b2f6SOder Chiou break;
41181319b2f6SOder Chiou
41191319b2f6SOder Chiou case RT5645_DMIC_DATA_GPIO12:
41201319b2f6SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1,
412153f9b3baSAxel Lin RT5645_DMIC_2_DP_MASK, RT5645_DMIC_2_DP_GPIO12);
41221319b2f6SOder Chiou regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1,
41231319b2f6SOder Chiou RT5645_GP12_PIN_MASK,
41241319b2f6SOder Chiou RT5645_GP12_PIN_DMIC2_SDA);
41251319b2f6SOder Chiou break;
41261319b2f6SOder Chiou
41271319b2f6SOder Chiou default:
41281319b2f6SOder Chiou break;
41291319b2f6SOder Chiou }
41301319b2f6SOder Chiou
4131ac4fc3eeSBard Liao if (rt5645->pdata.jd_mode) {
4132bb656addSBard Liao regmap_update_bits(rt5645->regmap, RT5645_GEN_CTRL3,
4133ac4fc3eeSBard Liao RT5645_IRQ_CLK_GATE_CTRL,
4134ac4fc3eeSBard Liao RT5645_IRQ_CLK_GATE_CTRL);
4135bb656addSBard Liao regmap_update_bits(rt5645->regmap, RT5645_MICBIAS,
4136bb656addSBard Liao RT5645_IRQ_CLK_INT, RT5645_IRQ_CLK_INT);
41372d4e2d02SBard Liao regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
41382d4e2d02SBard Liao RT5645_IRQ_JD_1_1_EN, RT5645_IRQ_JD_1_1_EN);
41392d4e2d02SBard Liao regmap_update_bits(rt5645->regmap, RT5645_GEN_CTRL3,
41402d4e2d02SBard Liao RT5645_JD_PSV_MODE, RT5645_JD_PSV_MODE);
41412d4e2d02SBard Liao regmap_update_bits(rt5645->regmap, RT5645_HPO_MIXER,
41422d4e2d02SBard Liao RT5645_IRQ_PSV_MODE, RT5645_IRQ_PSV_MODE);
41432d4e2d02SBard Liao regmap_update_bits(rt5645->regmap, RT5645_MICBIAS,
41442d4e2d02SBard Liao RT5645_MIC2_OVCD_EN, RT5645_MIC2_OVCD_EN);
41452d4e2d02SBard Liao regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1,
41462d4e2d02SBard Liao RT5645_GP1_PIN_IRQ, RT5645_GP1_PIN_IRQ);
41472d4e2d02SBard Liao switch (rt5645->pdata.jd_mode) {
41482d4e2d02SBard Liao case 1:
41492d4e2d02SBard Liao regmap_update_bits(rt5645->regmap, RT5645_A_JD_CTRL1,
41502d4e2d02SBard Liao RT5645_JD1_MODE_MASK,
41512d4e2d02SBard Liao RT5645_JD1_MODE_0);
41522d4e2d02SBard Liao break;
41532d4e2d02SBard Liao case 2:
41542d4e2d02SBard Liao regmap_update_bits(rt5645->regmap, RT5645_A_JD_CTRL1,
41552d4e2d02SBard Liao RT5645_JD1_MODE_MASK,
41562d4e2d02SBard Liao RT5645_JD1_MODE_1);
41572d4e2d02SBard Liao break;
41582d4e2d02SBard Liao case 3:
4159e7cfd867SJacob Rasmussen case 4:
41602d4e2d02SBard Liao regmap_update_bits(rt5645->regmap, RT5645_A_JD_CTRL1,
41612d4e2d02SBard Liao RT5645_JD1_MODE_MASK,
41622d4e2d02SBard Liao RT5645_JD1_MODE_2);
41632d4e2d02SBard Liao break;
41642d4e2d02SBard Liao default:
41652d4e2d02SBard Liao break;
41662d4e2d02SBard Liao }
4167aea086ddSBard Liao if (rt5645->pdata.inv_jd1_1) {
4168aea086ddSBard Liao regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
4169aea086ddSBard Liao RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
4170aea086ddSBard Liao }
41712d4e2d02SBard Liao }
41722d4e2d02SBard Liao
417302c5c032SBard Liao regmap_update_bits(rt5645->regmap, RT5645_ADDA_CLK1,
417402c5c032SBard Liao RT5645_I2S_PD1_MASK, RT5645_I2S_PD1_2);
417502c5c032SBard Liao
417689575022SBard Liao if (rt5645->pdata.level_trigger_irq) {
41777ff6319eSBard Liao regmap_update_bits(rt5645->regmap, RT5645_IRQ_CTRL2,
41787ff6319eSBard Liao RT5645_JD_1_1_MASK, RT5645_JD_1_1_INV);
4179381437ddSBard Liao }
41807211ec63SKees Cook timer_setup(&rt5645->btn_check_timer, rt5645_btn_check_callback, 0);
41817ff6319eSBard Liao
41828f82f2e4SShuming Fan mutex_init(&rt5645->jd_mutex);
41837ea3470aSNicolas Boichat INIT_DELAYED_WORK(&rt5645->jack_detect_work, rt5645_jack_detect_work);
41847099ee85SOder Chiou INIT_DELAYED_WORK(&rt5645->rcclock_work, rt5645_rcclock_work);
41857ea3470aSNicolas Boichat
4186f3fa1bbdSOder Chiou if (rt5645->i2c->irq) {
4187f3fa1bbdSOder Chiou ret = request_threaded_irq(rt5645->i2c->irq, NULL, rt5645_irq,
4188f3fa1bbdSOder Chiou IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
4189f3fa1bbdSOder Chiou | IRQF_ONESHOT, "rt5645", rt5645);
41905168c547SKoro Chen if (ret) {
4191f3fa1bbdSOder Chiou dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
41929fc114c5SKoro Chen goto err_enable;
41935168c547SKoro Chen }
4194f3fa1bbdSOder Chiou }
4195f3fa1bbdSOder Chiou
419679223bf1SKuninori Morimoto ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_dev_rt5645,
41971319b2f6SOder Chiou rt5645_dai, ARRAY_SIZE(rt5645_dai));
41985168c547SKoro Chen if (ret)
41995168c547SKoro Chen goto err_irq;
42005168c547SKoro Chen
42015168c547SKoro Chen return 0;
42025168c547SKoro Chen
42035168c547SKoro Chen err_irq:
42045168c547SKoro Chen if (rt5645->i2c->irq)
42055168c547SKoro Chen free_irq(rt5645->i2c->irq, rt5645);
42069fc114c5SKoro Chen err_enable:
42079fc114c5SKoro Chen regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies);
42085168c547SKoro Chen return ret;
42091319b2f6SOder Chiou }
42101319b2f6SOder Chiou
rt5645_i2c_remove(struct i2c_client * i2c)4211ed5c2f5fSUwe Kleine-König static void rt5645_i2c_remove(struct i2c_client *i2c)
42121319b2f6SOder Chiou {
4213f3fa1bbdSOder Chiou struct rt5645_priv *rt5645 = i2c_get_clientdata(i2c);
4214f3fa1bbdSOder Chiou
4215f3fa1bbdSOder Chiou if (i2c->irq)
4216f3fa1bbdSOder Chiou free_irq(i2c->irq, rt5645);
4217f3fa1bbdSOder Chiou
42182def44d3SLin Ma /*
42192def44d3SLin Ma * Since the rt5645_btn_check_callback() can queue jack_detect_work,
42202def44d3SLin Ma * the timer need to be delted first
42212def44d3SLin Ma */
42222def44d3SLin Ma del_timer_sync(&rt5645->btn_check_timer);
42232def44d3SLin Ma
4224cd6e82b8SOder Chiou cancel_delayed_work_sync(&rt5645->jack_detect_work);
42257099ee85SOder Chiou cancel_delayed_work_sync(&rt5645->rcclock_work);
4226cd6e82b8SOder Chiou
4227*7904b066SDerek Fang if (rt5645->gpiod_cbj_sleeve)
4228*7904b066SDerek Fang gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
4229*7904b066SDerek Fang
42309fc114c5SKoro Chen regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies);
42311319b2f6SOder Chiou }
42321319b2f6SOder Chiou
rt5645_i2c_shutdown(struct i2c_client * i2c)4233f2988afeSOder Chiou static void rt5645_i2c_shutdown(struct i2c_client *i2c)
4234f2988afeSOder Chiou {
4235f2988afeSOder Chiou struct rt5645_priv *rt5645 = i2c_get_clientdata(i2c);
4236f2988afeSOder Chiou
4237f2988afeSOder Chiou regmap_update_bits(rt5645->regmap, RT5645_GEN_CTRL3,
4238f2988afeSOder Chiou RT5645_RING2_SLEEVE_GND, RT5645_RING2_SLEEVE_GND);
4239f2988afeSOder Chiou regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL2, RT5645_CBJ_MN_JD,
4240f2988afeSOder Chiou RT5645_CBJ_MN_JD);
4241f2988afeSOder Chiou regmap_update_bits(rt5645->regmap, RT5645_IN1_CTRL1, RT5645_CBJ_BST1_EN,
4242f2988afeSOder Chiou 0);
4243a2c026cfSOder Chiou msleep(20);
4244a2c026cfSOder Chiou regmap_write(rt5645->regmap, RT5645_RESET, 0);
4245*7904b066SDerek Fang
4246*7904b066SDerek Fang if (rt5645->gpiod_cbj_sleeve)
4247*7904b066SDerek Fang gpiod_set_value(rt5645->gpiod_cbj_sleeve, 0);
4248f2988afeSOder Chiou }
4249f2988afeSOder Chiou
rt5645_sys_suspend(struct device * dev)4250c7a0f10bSShuming Fan static int __maybe_unused rt5645_sys_suspend(struct device *dev)
4251c7a0f10bSShuming Fan {
4252c7a0f10bSShuming Fan struct rt5645_priv *rt5645 = dev_get_drvdata(dev);
4253c7a0f10bSShuming Fan
4254c7a0f10bSShuming Fan del_timer_sync(&rt5645->btn_check_timer);
4255c7a0f10bSShuming Fan cancel_delayed_work_sync(&rt5645->jack_detect_work);
4256c7a0f10bSShuming Fan cancel_delayed_work_sync(&rt5645->rcclock_work);
4257c7a0f10bSShuming Fan
4258c7a0f10bSShuming Fan regcache_cache_only(rt5645->regmap, true);
4259c7a0f10bSShuming Fan regcache_mark_dirty(rt5645->regmap);
4260c7a0f10bSShuming Fan return 0;
4261c7a0f10bSShuming Fan }
4262c7a0f10bSShuming Fan
rt5645_sys_resume(struct device * dev)4263c7a0f10bSShuming Fan static int __maybe_unused rt5645_sys_resume(struct device *dev)
4264c7a0f10bSShuming Fan {
4265c7a0f10bSShuming Fan struct rt5645_priv *rt5645 = dev_get_drvdata(dev);
4266c7a0f10bSShuming Fan
4267c7a0f10bSShuming Fan regcache_cache_only(rt5645->regmap, false);
4268c7a0f10bSShuming Fan regcache_sync(rt5645->regmap);
4269c7a0f10bSShuming Fan
4270c7a0f10bSShuming Fan if (rt5645->hp_jack) {
4271c7a0f10bSShuming Fan rt5645->jack_type = 0;
4272aa98697cSShuming Fan rt5645_jack_detect_work(&rt5645->jack_detect_work.work);
4273c7a0f10bSShuming Fan }
4274c7a0f10bSShuming Fan return 0;
4275c7a0f10bSShuming Fan }
4276c7a0f10bSShuming Fan
4277c7a0f10bSShuming Fan static const struct dev_pm_ops rt5645_pm = {
4278c7a0f10bSShuming Fan SET_SYSTEM_SLEEP_PM_OPS(rt5645_sys_suspend, rt5645_sys_resume)
4279c7a0f10bSShuming Fan };
4280c7a0f10bSShuming Fan
42819e22f782SOder Chiou static struct i2c_driver rt5645_i2c_driver = {
42821319b2f6SOder Chiou .driver = {
42831319b2f6SOder Chiou .name = "rt5645",
42849ba2da5fSJavier Martinez Canillas .of_match_table = of_match_ptr(rt5645_of_match),
42853168c201SFang, Yang A .acpi_match_table = ACPI_PTR(rt5645_acpi_match),
4286c7a0f10bSShuming Fan .pm = &rt5645_pm,
42871319b2f6SOder Chiou },
42889abcd240SUwe Kleine-König .probe = rt5645_i2c_probe,
42891319b2f6SOder Chiou .remove = rt5645_i2c_remove,
4290f2988afeSOder Chiou .shutdown = rt5645_i2c_shutdown,
42911319b2f6SOder Chiou .id_table = rt5645_i2c_id,
42921319b2f6SOder Chiou };
42931319b2f6SOder Chiou module_i2c_driver(rt5645_i2c_driver);
42941319b2f6SOder Chiou
42951319b2f6SOder Chiou MODULE_DESCRIPTION("ASoC RT5645 driver");
42961319b2f6SOder Chiou MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>");
42971319b2f6SOder Chiou MODULE_LICENSE("GPL v2");
4298