Commit 412665b46134f93464c09405e02f08ac9c62526d
Exists in
master
and in
53 other branches
Merge branch 'u-boot-samsung/master' into 'u-boot-arm/master'
Showing 26 changed files Side-by-side Diff
- MAINTAINERS
- arch/arm/cpu/armv7/exynos/power.c
- arch/arm/dts/exynos5250.dtsi
- arch/arm/include/asm/arch-exynos/power.h
- arch/arm/include/asm/arch-exynos/spl.h
- arch/arm/include/asm/arch-exynos/tmu.h
- board/samsung/dts/exynos5250-smdk5250.dts
- board/samsung/dts/exynos5250-snow.dts
- board/samsung/smdk5250/smdk5250.c
- boards.cfg
- common/cmd_dtt.c
- doc/device-tree-bindings/exynos/tmu.txt
- drivers/mmc/sdhci.c
- drivers/power/Makefile
- drivers/power/exynos-tmu.c
- drivers/sound/Makefile
- drivers/sound/max98095.c
- drivers/sound/max98095.h
- drivers/sound/sound.c
- include/configs/exynos5250-dt.h
- include/configs/snow.h
- include/fdtdec.h
- include/power/max77686_pmic.h
- include/sound.h
- include/tmu.h
- lib/fdtdec.c
MAINTAINERS
... | ... | @@ -914,6 +914,10 @@ |
914 | 914 | Bo Shen <voice.shen@atmel.com> |
915 | 915 | at91sam9x5ek ARM926EJS (AT91SAM9G15,G25,G35,X25,X35 SoC) |
916 | 916 | |
917 | +Rajeshwari Shinde <rajeshwari.s@samsung.com> | |
918 | + | |
919 | + snow ARM ARMV7 (EXYNOS5250 SoC) | |
920 | + | |
917 | 921 | Michal Simek <monstr@monstr.eu> |
918 | 922 | |
919 | 923 | zynq ARM ARMV7 (Zynq SoC) |
arch/arm/cpu/armv7/exynos/power.c
... | ... | @@ -95,4 +95,49 @@ |
95 | 95 | if (cpu_is_exynos5()) |
96 | 96 | exynos5_dp_phy_control(enable); |
97 | 97 | } |
98 | + | |
99 | +static void exynos5_set_ps_hold_ctrl(void) | |
100 | +{ | |
101 | + struct exynos5_power *power = | |
102 | + (struct exynos5_power *)samsung_get_base_power(); | |
103 | + | |
104 | + /* Set PS-Hold high */ | |
105 | + setbits_le32(&power->ps_hold_control, | |
106 | + EXYNOS_PS_HOLD_CONTROL_DATA_HIGH); | |
107 | +} | |
108 | + | |
109 | +void set_ps_hold_ctrl(void) | |
110 | +{ | |
111 | + if (cpu_is_exynos5()) | |
112 | + exynos5_set_ps_hold_ctrl(); | |
113 | +} | |
114 | + | |
115 | + | |
116 | +static void exynos5_set_xclkout(void) | |
117 | +{ | |
118 | + struct exynos5_power *power = | |
119 | + (struct exynos5_power *)samsung_get_base_power(); | |
120 | + | |
121 | + /* use xxti for xclk out */ | |
122 | + clrsetbits_le32(&power->pmu_debug, PMU_DEBUG_CLKOUT_SEL_MASK, | |
123 | + PMU_DEBUG_XXTI); | |
124 | +} | |
125 | + | |
126 | +void set_xclkout(void) | |
127 | +{ | |
128 | + if (cpu_is_exynos5()) | |
129 | + exynos5_set_xclkout(); | |
130 | +} | |
131 | + | |
132 | +/* Enables hardware tripping to power off the system when TMU fails */ | |
133 | +void set_hw_thermal_trip(void) | |
134 | +{ | |
135 | + if (cpu_is_exynos5()) { | |
136 | + struct exynos5_power *power = | |
137 | + (struct exynos5_power *)samsung_get_base_power(); | |
138 | + | |
139 | + /* PS_HOLD_CONTROL register ENABLE_HW_TRIP bit*/ | |
140 | + setbits_le32(&power->ps_hold_control, POWER_ENABLE_HW_TRIP); | |
141 | + } | |
142 | +} |
arch/arm/dts/exynos5250.dtsi
arch/arm/include/asm/arch-exynos/power.h
... | ... | @@ -857,6 +857,9 @@ |
857 | 857 | |
858 | 858 | void set_usbhost_phy_ctrl(unsigned int enable); |
859 | 859 | |
860 | +/* Enables hardware tripping to power off the system when TMU fails */ | |
861 | +void set_hw_thermal_trip(void); | |
862 | + | |
860 | 863 | #define POWER_USB_HOST_PHY_CTRL_EN (1 << 0) |
861 | 864 | #define POWER_USB_HOST_PHY_CTRL_DISABLE (0 << 0) |
862 | 865 | |
... | ... | @@ -864,5 +867,26 @@ |
864 | 867 | |
865 | 868 | #define EXYNOS_DP_PHY_ENABLE (1 << 0) |
866 | 869 | |
870 | +#define EXYNOS_PS_HOLD_CONTROL_DATA_HIGH (1 << 8) | |
871 | +#define POWER_ENABLE_HW_TRIP (1UL << 31) | |
872 | + | |
873 | +/* | |
874 | + * Set ps_hold data driving value high | |
875 | + * This enables the machine to stay powered on | |
876 | + * after the initial power-on condition goes away | |
877 | + * (e.g. power button). | |
878 | + */ | |
879 | +void set_ps_hold_ctrl(void); | |
880 | + | |
881 | +/* PMU_DEBUG bits [12:8] = 0x1000 selects XXTI clock source */ | |
882 | +#define PMU_DEBUG_XXTI 0x1000 | |
883 | +/* Mask bit[12:8] for xxti clock selection */ | |
884 | +#define PMU_DEBUG_CLKOUT_SEL_MASK 0x1f00 | |
885 | + | |
886 | +/* | |
887 | + * Pmu debug is used for xclkout, enable xclkout with | |
888 | + * source as XXTI | |
889 | + */ | |
890 | +void set_xclkout(void); | |
867 | 891 | #endif |
arch/arm/include/asm/arch-exynos/spl.h
... | ... | @@ -78,11 +78,12 @@ |
78 | 78 | */ |
79 | 79 | u32 uboot_size; |
80 | 80 | enum boot_mode boot_source; /* Boot device */ |
81 | - enum mem_manuf mem_manuf; /* Memory Manufacturer */ | |
82 | 81 | unsigned frequency_mhz; /* Frequency of memory in MHz */ |
83 | 82 | unsigned arm_freq_mhz; /* ARM Frequency in MHz */ |
84 | 83 | u32 serial_base; /* Serial base address */ |
85 | 84 | u32 i2c_base; /* i2c base address */ |
85 | + u32 board_rev_gpios; /* Board revision GPIOs */ | |
86 | + enum mem_manuf mem_manuf; /* Memory Manufacturer */ | |
86 | 87 | } __attribute__((__packed__)); |
87 | 88 | #endif |
88 | 89 |
arch/arm/include/asm/arch-exynos/tmu.h
1 | +/* | |
2 | + * Copyright (c) 2012 Samsung Electronics Co., Ltd. | |
3 | + * http://www.samsung.com | |
4 | + * Akshay Saraswat <akshay.s@samsung.com> | |
5 | + * | |
6 | + * EXYNOS - Thermal Management Unit | |
7 | + * | |
8 | + * See file CREDITS for list of people who contributed to this | |
9 | + * project. | |
10 | + * | |
11 | + * This program is free software; you can redistribute it and/or modify | |
12 | + * it under the terms of the GNU General Public License version 2 as | |
13 | + * published by the Free Software Foundation. | |
14 | + * You should have received a copy of the GNU General Public License | |
15 | + * along with this program; if not, write to the Free Software | |
16 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
17 | + * MA 02111-1307 USA | |
18 | + */ | |
19 | + | |
20 | +#ifndef __ASM_ARCH_TMU_H | |
21 | +#define __ASM_ARCH_TMU_H | |
22 | + | |
23 | +struct exynos5_tmu_reg { | |
24 | + unsigned triminfo; | |
25 | + unsigned rsvd1; | |
26 | + unsigned rsvd2; | |
27 | + unsigned rsvd3; | |
28 | + unsigned rsvd4; | |
29 | + unsigned triminfo_control; | |
30 | + unsigned rsvd5; | |
31 | + unsigned rsvd6; | |
32 | + unsigned tmu_control; | |
33 | + unsigned rsvd7; | |
34 | + unsigned tmu_status; | |
35 | + unsigned sampling_internal; | |
36 | + unsigned counter_value0; | |
37 | + unsigned counter_value1; | |
38 | + unsigned rsvd8; | |
39 | + unsigned rsvd9; | |
40 | + unsigned current_temp; | |
41 | + unsigned rsvd10; | |
42 | + unsigned rsvd11; | |
43 | + unsigned rsvd12; | |
44 | + unsigned threshold_temp_rise; | |
45 | + unsigned threshold_temp_fall; | |
46 | + unsigned rsvd13; | |
47 | + unsigned rsvd14; | |
48 | + unsigned past_temp3_0; | |
49 | + unsigned past_temp7_4; | |
50 | + unsigned past_temp11_8; | |
51 | + unsigned past_temp15_12; | |
52 | + unsigned inten; | |
53 | + unsigned intstat; | |
54 | + unsigned intclear; | |
55 | + unsigned rsvd15; | |
56 | + unsigned emul_con; | |
57 | +}; | |
58 | +#endif /* __ASM_ARCH_TMU_H */ |
board/samsung/dts/exynos5250-smdk5250.dts
... | ... | @@ -66,5 +66,18 @@ |
66 | 66 | compatible = "maxim,max77686_pmic"; |
67 | 67 | }; |
68 | 68 | }; |
69 | + | |
70 | + tmu@10060000 { | |
71 | + samsung,min-temp = <25>; | |
72 | + samsung,max-temp = <125>; | |
73 | + samsung,start-warning = <95>; | |
74 | + samsung,start-tripping = <105>; | |
75 | + samsung,hw-tripping = <110>; | |
76 | + samsung,efuse-min-value = <40>; | |
77 | + samsung,efuse-value = <55>; | |
78 | + samsung,efuse-max-value = <100>; | |
79 | + samsung,slope = <274761730>; | |
80 | + samsung,dc-value = <25>; | |
81 | + }; | |
69 | 82 | }; |
board/samsung/dts/exynos5250-snow.dts
1 | +/* | |
2 | + * SAMSUNG Snow board device tree source | |
3 | + * | |
4 | + * Copyright (c) 2012 Samsung Electronics Co., Ltd. | |
5 | + * http://www.samsung.com | |
6 | + * | |
7 | + * This program is free software; you can redistribute it and/or modify | |
8 | + * it under the terms of the GNU General Public License version 2 as | |
9 | + * published by the Free Software Foundation. | |
10 | +*/ | |
11 | + | |
12 | +/dts-v1/; | |
13 | +/include/ ARCH_CPU_DTS | |
14 | + | |
15 | +/ { | |
16 | + model = "Google Snow"; | |
17 | + compatible = "google,snow", "samsung,exynos5250"; | |
18 | + | |
19 | + aliases { | |
20 | + i2c0 = "/i2c@12c60000"; | |
21 | + i2c1 = "/i2c@12c70000"; | |
22 | + i2c2 = "/i2c@12c80000"; | |
23 | + i2c3 = "/i2c@12c90000"; | |
24 | + i2c4 = "/i2c@12ca0000"; | |
25 | + i2c5 = "/i2c@12cb0000"; | |
26 | + i2c6 = "/i2c@12cc0000"; | |
27 | + i2c7 = "/i2c@12cd0000"; | |
28 | + spi0 = "/spi@12d20000"; | |
29 | + spi1 = "/spi@12d30000"; | |
30 | + spi2 = "/spi@12d40000"; | |
31 | + spi3 = "/spi@131a0000"; | |
32 | + spi4 = "/spi@131b0000"; | |
33 | + }; | |
34 | + | |
35 | + sound@12d60000 { | |
36 | + samsung,i2s-epll-clock-frequency = <192000000>; | |
37 | + samsung,i2s-sampling-rate = <48000>; | |
38 | + samsung,i2s-bits-per-sample = <16>; | |
39 | + samsung,i2s-channels = <2>; | |
40 | + samsung,i2s-lr-clk-framesize = <256>; | |
41 | + samsung,i2s-bit-clk-framesize = <32>; | |
42 | + samsung,codec-type = "max98095"; | |
43 | + }; | |
44 | + | |
45 | + i2c@12cd0000 { | |
46 | + soundcodec@22 { | |
47 | + reg = <0x22>; | |
48 | + compatible = "maxim,max98095-codec"; | |
49 | + }; | |
50 | + }; | |
51 | + | |
52 | + i2c@12c60000 { | |
53 | + pmic@9 { | |
54 | + reg = <0x9>; | |
55 | + compatible = "maxim,max77686_pmic"; | |
56 | + }; | |
57 | + }; | |
58 | +}; |
board/samsung/smdk5250/smdk5250.c
... | ... | @@ -23,6 +23,7 @@ |
23 | 23 | #include <common.h> |
24 | 24 | #include <fdtdec.h> |
25 | 25 | #include <asm/io.h> |
26 | +#include <errno.h> | |
26 | 27 | #include <i2c.h> |
27 | 28 | #include <lcd.h> |
28 | 29 | #include <netdev.h> |
29 | 30 | |
... | ... | @@ -35,9 +36,40 @@ |
35 | 36 | #include <asm/arch/sromc.h> |
36 | 37 | #include <asm/arch/dp_info.h> |
37 | 38 | #include <power/pmic.h> |
39 | +#include <power/max77686_pmic.h> | |
40 | +#include <tmu.h> | |
38 | 41 | |
39 | 42 | DECLARE_GLOBAL_DATA_PTR; |
40 | 43 | |
44 | +#if defined CONFIG_EXYNOS_TMU | |
45 | +/* | |
46 | + * Boot Time Thermal Analysis for SoC temperature threshold breach | |
47 | + */ | |
48 | +static void boot_temp_check(void) | |
49 | +{ | |
50 | + int temp; | |
51 | + | |
52 | + switch (tmu_monitor(&temp)) { | |
53 | + /* Status TRIPPED ans WARNING means corresponding threshold breach */ | |
54 | + case TMU_STATUS_TRIPPED: | |
55 | + puts("EXYNOS_TMU: TRIPPING! Device power going down ...\n"); | |
56 | + set_ps_hold_ctrl(); | |
57 | + hang(); | |
58 | + break; | |
59 | + case TMU_STATUS_WARNING: | |
60 | + puts("EXYNOS_TMU: WARNING! Temperature very high\n"); | |
61 | + break; | |
62 | + /* | |
63 | + * TMU_STATUS_INIT means something is wrong with temperature sensing | |
64 | + * and TMU status was changed back from NORMAL to INIT. | |
65 | + */ | |
66 | + case TMU_STATUS_INIT: | |
67 | + default: | |
68 | + debug("EXYNOS_TMU: Unknown TMU state\n"); | |
69 | + } | |
70 | +} | |
71 | +#endif | |
72 | + | |
41 | 73 | #ifdef CONFIG_USB_EHCI_EXYNOS |
42 | 74 | int board_usb_vbus_init(void) |
43 | 75 | { |
44 | 76 | |
45 | 77 | |
... | ... | @@ -54,15 +86,39 @@ |
54 | 86 | } |
55 | 87 | #endif |
56 | 88 | |
89 | +#ifdef CONFIG_SOUND_MAX98095 | |
90 | +static void board_enable_audio_codec(void) | |
91 | +{ | |
92 | + struct exynos5_gpio_part1 *gpio1 = (struct exynos5_gpio_part1 *) | |
93 | + samsung_get_base_gpio_part1(); | |
94 | + | |
95 | + /* Enable MAX98095 Codec */ | |
96 | + s5p_gpio_direction_output(&gpio1->x1, 7, 1); | |
97 | + s5p_gpio_set_pull(&gpio1->x1, 7, GPIO_PULL_NONE); | |
98 | +} | |
99 | +#endif | |
100 | + | |
57 | 101 | int board_init(void) |
58 | 102 | { |
59 | 103 | gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL); |
104 | + | |
105 | +#if defined CONFIG_EXYNOS_TMU | |
106 | + if (tmu_init(gd->fdt_blob) != TMU_STATUS_NORMAL) { | |
107 | + debug("%s: Failed to init TMU\n", __func__); | |
108 | + return -1; | |
109 | + } | |
110 | + boot_temp_check(); | |
111 | +#endif | |
112 | + | |
60 | 113 | #ifdef CONFIG_EXYNOS_SPI |
61 | 114 | spi_init(); |
62 | 115 | #endif |
63 | 116 | #ifdef CONFIG_USB_EHCI_EXYNOS |
64 | 117 | board_usb_vbus_init(); |
65 | 118 | #endif |
119 | +#ifdef CONFIG_SOUND_MAX98095 | |
120 | + board_enable_audio_codec(); | |
121 | +#endif | |
66 | 122 | return 0; |
67 | 123 | } |
68 | 124 | |
69 | 125 | |
70 | 126 | |
... | ... | @@ -80,12 +136,119 @@ |
80 | 136 | } |
81 | 137 | |
82 | 138 | #if defined(CONFIG_POWER) |
139 | +static int pmic_reg_update(struct pmic *p, int reg, uint regval) | |
140 | +{ | |
141 | + u32 val; | |
142 | + int ret = 0; | |
143 | + | |
144 | + ret = pmic_reg_read(p, reg, &val); | |
145 | + if (ret) { | |
146 | + debug("%s: PMIC %d register read failed\n", __func__, reg); | |
147 | + return -1; | |
148 | + } | |
149 | + val |= regval; | |
150 | + ret = pmic_reg_write(p, reg, val); | |
151 | + if (ret) { | |
152 | + debug("%s: PMIC %d register write failed\n", __func__, reg); | |
153 | + return -1; | |
154 | + } | |
155 | + return 0; | |
156 | +} | |
157 | + | |
83 | 158 | int power_init_board(void) |
84 | 159 | { |
160 | + struct pmic *p; | |
161 | + | |
162 | + set_ps_hold_ctrl(); | |
163 | + | |
164 | + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); | |
165 | + | |
85 | 166 | if (pmic_init(I2C_PMIC)) |
86 | 167 | return -1; |
87 | - else | |
88 | - return 0; | |
168 | + | |
169 | + p = pmic_get("MAX77686_PMIC"); | |
170 | + if (!p) | |
171 | + return -ENODEV; | |
172 | + | |
173 | + if (pmic_probe(p)) | |
174 | + return -1; | |
175 | + | |
176 | + if (pmic_reg_update(p, MAX77686_REG_PMIC_32KHZ, MAX77686_32KHCP_EN)) | |
177 | + return -1; | |
178 | + | |
179 | + if (pmic_reg_update(p, MAX77686_REG_PMIC_BBAT, | |
180 | + MAX77686_BBCHOSTEN | MAX77686_BBCVS_3_5V)) | |
181 | + return -1; | |
182 | + | |
183 | + /* VDD_MIF */ | |
184 | + if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK1OUT, | |
185 | + MAX77686_BUCK1OUT_1V)) { | |
186 | + debug("%s: PMIC %d register write failed\n", __func__, | |
187 | + MAX77686_REG_PMIC_BUCK1OUT); | |
188 | + return -1; | |
189 | + } | |
190 | + | |
191 | + if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK1CRTL, | |
192 | + MAX77686_BUCK1CTRL_EN)) | |
193 | + return -1; | |
194 | + | |
195 | + /* VDD_ARM */ | |
196 | + if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK2DVS1, | |
197 | + MAX77686_BUCK2DVS1_1_3V)) { | |
198 | + debug("%s: PMIC %d register write failed\n", __func__, | |
199 | + MAX77686_REG_PMIC_BUCK2DVS1); | |
200 | + return -1; | |
201 | + } | |
202 | + | |
203 | + if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK2CTRL1, | |
204 | + MAX77686_BUCK2CTRL_ON)) | |
205 | + return -1; | |
206 | + | |
207 | + /* VDD_INT */ | |
208 | + if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK3DVS1, | |
209 | + MAX77686_BUCK3DVS1_1_0125V)) { | |
210 | + debug("%s: PMIC %d register write failed\n", __func__, | |
211 | + MAX77686_REG_PMIC_BUCK3DVS1); | |
212 | + return -1; | |
213 | + } | |
214 | + | |
215 | + if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK3CTRL, | |
216 | + MAX77686_BUCK3CTRL_ON)) | |
217 | + return -1; | |
218 | + | |
219 | + /* VDD_G3D */ | |
220 | + if (pmic_reg_write(p, MAX77686_REG_PMIC_BUCK4DVS1, | |
221 | + MAX77686_BUCK4DVS1_1_2V)) { | |
222 | + debug("%s: PMIC %d register write failed\n", __func__, | |
223 | + MAX77686_REG_PMIC_BUCK4DVS1); | |
224 | + return -1; | |
225 | + } | |
226 | + | |
227 | + if (pmic_reg_update(p, MAX77686_REG_PMIC_BUCK4CTRL1, | |
228 | + MAX77686_BUCK3CTRL_ON)) | |
229 | + return -1; | |
230 | + | |
231 | + /* VDD_LDO2 */ | |
232 | + if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO2CTRL1, | |
233 | + MAX77686_LD02CTRL1_1_5V | EN_LDO)) | |
234 | + return -1; | |
235 | + | |
236 | + /* VDD_LDO3 */ | |
237 | + if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO3CTRL1, | |
238 | + MAX77686_LD03CTRL1_1_8V | EN_LDO)) | |
239 | + return -1; | |
240 | + | |
241 | + /* VDD_LDO5 */ | |
242 | + if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO5CTRL1, | |
243 | + MAX77686_LD05CTRL1_1_8V | EN_LDO)) | |
244 | + return -1; | |
245 | + | |
246 | + /* VDD_LDO10 */ | |
247 | + if (pmic_reg_update(p, MAX77686_REG_PMIC_LDO10CTRL1, | |
248 | + MAX77686_LD10CTRL1_1_8V | EN_LDO)) | |
249 | + return -1; | |
250 | + | |
251 | + return 0; | |
89 | 252 | } |
90 | 253 | #endif |
91 | 254 | |
92 | 255 | |
... | ... | @@ -212,8 +375,17 @@ |
212 | 375 | #ifdef CONFIG_DISPLAY_BOARDINFO |
213 | 376 | int checkboard(void) |
214 | 377 | { |
215 | - printf("\nBoard: SMDK5250\n"); | |
378 | +#ifdef CONFIG_OF_CONTROL | |
379 | + const char *board_name; | |
216 | 380 | |
381 | + board_name = fdt_getprop(gd->fdt_blob, 0, "model", NULL); | |
382 | + if (board_name == NULL) | |
383 | + printf("\nUnknown Board\n"); | |
384 | + else | |
385 | + printf("\nBoard: %s\n", board_name); | |
386 | +#else | |
387 | + printf("\nBoard: SMDK5250\n"); | |
388 | +#endif | |
217 | 389 | return 0; |
218 | 390 | } |
219 | 391 | #endif |
boards.cfg
... | ... | @@ -298,6 +298,7 @@ |
298 | 298 | smdkc100 arm armv7 smdkc100 samsung s5pc1xx |
299 | 299 | origen arm armv7 origen samsung exynos |
300 | 300 | s5pc210_universal arm armv7 universal_c210 samsung exynos |
301 | +snow arm armv7 smdk5250 samsung exynos | |
301 | 302 | smdk5250 arm armv7 smdk5250 samsung exynos |
302 | 303 | smdkv310 arm armv7 smdkv310 samsung exynos |
303 | 304 | trats arm armv7 trats samsung exynos |
common/cmd_dtt.c
... | ... | @@ -27,7 +27,9 @@ |
27 | 27 | |
28 | 28 | #include <dtt.h> |
29 | 29 | #include <i2c.h> |
30 | +#include <tmu.h> | |
30 | 31 | |
32 | +#if defined CONFIG_DTT_SENSORS | |
31 | 33 | static unsigned long sensor_initialized; |
32 | 34 | |
33 | 35 | static void _initialize_dtt(void) |
34 | 36 | |
35 | 37 | |
... | ... | @@ -59,9 +61,11 @@ |
59 | 61 | /* switch back to original I2C bus */ |
60 | 62 | I2C_SET_BUS(old_bus); |
61 | 63 | } |
64 | +#endif | |
62 | 65 | |
63 | -int do_dtt (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) | |
66 | +int dtt_i2c(void) | |
64 | 67 | { |
68 | +#if defined CONFIG_DTT_SENSORS | |
65 | 69 | int i; |
66 | 70 | unsigned char sensors[] = CONFIG_DTT_SENSORS; |
67 | 71 | int old_bus; |
68 | 72 | |
... | ... | @@ -83,8 +87,34 @@ |
83 | 87 | |
84 | 88 | /* switch back to original I2C bus */ |
85 | 89 | I2C_SET_BUS(old_bus); |
90 | +#endif | |
86 | 91 | |
87 | 92 | return 0; |
93 | +} | |
94 | + | |
95 | +int dtt_tmu(void) | |
96 | +{ | |
97 | +#if defined CONFIG_TMU_CMD_DTT | |
98 | + int cur_temp; | |
99 | + | |
100 | + /* Sense and return latest thermal info */ | |
101 | + if (tmu_monitor(&cur_temp) == TMU_STATUS_INIT) { | |
102 | + puts("TMU is in unknown state, temperature is invalid\n"); | |
103 | + return -1; | |
104 | + } | |
105 | + printf("Current temperature: %u degrees Celsius\n", cur_temp); | |
106 | +#endif | |
107 | + return 0; | |
108 | +} | |
109 | + | |
110 | +int do_dtt(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) | |
111 | +{ | |
112 | + int err = 0; | |
113 | + | |
114 | + err |= dtt_i2c(); | |
115 | + err |= dtt_tmu(); | |
116 | + | |
117 | + return err; | |
88 | 118 | } /* do_dtt() */ |
89 | 119 | |
90 | 120 | /***************************************************/ |
doc/device-tree-bindings/exynos/tmu.txt
1 | +Exynos Thermal management Unit | |
2 | + | |
3 | +Required properties: | |
4 | + | |
5 | + - compatible : Should be "samsung,exynos-tmu" for TMU | |
6 | + - samsung,min-temp : Minimum temperature value (25 degree celsius) | |
7 | + - Current temperature of SoC should be more than this value. | |
8 | + - samsung,max-temp : Maximum temperature value (125 degree celsius) | |
9 | + - Current temperature of SoC should be less than this value. | |
10 | + - samsung,start-warning : Temperature at which TMU starts giving warning (degree celsius) | |
11 | + - samsung,start-tripping : Temperature at which TMU shuts down the system (degree celsius) | |
12 | + - samsung,hw-tripping : Temperature at which hardware tripping should happen | |
13 | + in case TMU fails to power off (degree celsius) | |
14 | + - samsung,efuse-min-value : SOC efuse min value (Constant 40) | |
15 | + - efuse-value should be more than this value. | |
16 | + - samsung,efuse-value : SOC actual efuse value (Literal value) | |
17 | + - This is the data trimming info. | |
18 | + - This value is used to calculate measuring error. | |
19 | + - samsung,efuse-max-value : SoC max efuse value (Constant 100) | |
20 | + - efuse-value should be less than this value. | |
21 | + - samsung,slope : Default value 274761730 (Constant 0x1060_8802). | |
22 | + - This is the default value for TMU_CONTROL register. | |
23 | + - It sets the gain of amplifier to the positive-tc generator block. | |
24 | + - It selects thermal tripping mode and enables thermal tripping. | |
25 | + - samsung,dc-value : Measured data calibration value (Constant 25) | |
26 | + - Used for tempearture calculation. | |
27 | + - This is 25 because temperature measured is always above 25 degrees. | |
28 | + | |
29 | + | |
30 | +Example: | |
31 | + | |
32 | +tmu@10060000 { | |
33 | + compatible = "samsung,exynos-tmu" | |
34 | + samsung,min-temp = <25>; | |
35 | + samsung,max-temp = <125>; | |
36 | + samsung,start-warning = <95>; | |
37 | + samsung,start-tripping = <105>; | |
38 | + samsung,hw-tripping = <110>; | |
39 | + samsung,efuse-min-value = <40>; | |
40 | + samsung,efuse-value = <55>; | |
41 | + samsung,efuse-max-value = <100>; | |
42 | + samsung,slope = <274761730>; | |
43 | + samsung,dc-value = <25>; | |
44 | +}; |
drivers/mmc/sdhci.c
... | ... | @@ -412,9 +412,11 @@ |
412 | 412 | status = sdhci_readl(host, SDHCI_PRESENT_STATE); |
413 | 413 | } |
414 | 414 | |
415 | - /* Eable all state */ | |
416 | - sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_ENABLE); | |
417 | - sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_SIGNAL_ENABLE); | |
415 | + /* Enable only interrupts served by the SD controller */ | |
416 | + sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK | |
417 | + , SDHCI_INT_ENABLE); | |
418 | + /* Mask all sdhci interrupt sources */ | |
419 | + sdhci_writel(host, 0x0, SDHCI_SIGNAL_ENABLE); | |
418 | 420 | |
419 | 421 | return 0; |
420 | 422 | } |
drivers/power/Makefile
drivers/power/exynos-tmu.c
1 | +/* | |
2 | + * Copyright (c) 2012 Samsung Electronics Co., Ltd. | |
3 | + * http://www.samsung.com | |
4 | + * Akshay Saraswat <akshay.s@samsung.com> | |
5 | + * | |
6 | + * EXYNOS - Thermal Management Unit | |
7 | + * | |
8 | + * See file CREDITS for list of people who contributed to this | |
9 | + * project. | |
10 | + * | |
11 | + * This program is free software; you can redistribute it and/or modify | |
12 | + * it under the terms of the GNU General Public License version 2 as | |
13 | + * published by the Free Software Foundation. | |
14 | + * You should have received a copy of the GNU General Public License | |
15 | + * along with this program; if not, write to the Free Software | |
16 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
17 | + * MA 02111-1307 USA | |
18 | + */ | |
19 | + | |
20 | +#include <common.h> | |
21 | +#include <errno.h> | |
22 | +#include <fdtdec.h> | |
23 | +#include <tmu.h> | |
24 | +#include <asm/arch/tmu.h> | |
25 | +#include <asm/arch/power.h> | |
26 | + | |
27 | +#define TRIMINFO_RELOAD 1 | |
28 | +#define CORE_EN 1 | |
29 | +#define THERM_TRIP_EN (1 << 12) | |
30 | + | |
31 | +#define INTEN_RISE0 1 | |
32 | +#define INTEN_RISE1 (1 << 4) | |
33 | +#define INTEN_RISE2 (1 << 8) | |
34 | +#define INTEN_FALL0 (1 << 16) | |
35 | +#define INTEN_FALL1 (1 << 20) | |
36 | +#define INTEN_FALL2 (1 << 24) | |
37 | + | |
38 | +#define TRIM_INFO_MASK 0xff | |
39 | + | |
40 | +#define INTCLEAR_RISE0 1 | |
41 | +#define INTCLEAR_RISE1 (1 << 4) | |
42 | +#define INTCLEAR_RISE2 (1 << 8) | |
43 | +#define INTCLEAR_FALL0 (1 << 16) | |
44 | +#define INTCLEAR_FALL1 (1 << 20) | |
45 | +#define INTCLEAR_FALL2 (1 << 24) | |
46 | +#define INTCLEARALL (INTCLEAR_RISE0 | INTCLEAR_RISE1 | \ | |
47 | + INTCLEAR_RISE2 | INTCLEAR_FALL0 | \ | |
48 | + INTCLEAR_FALL1 | INTCLEAR_FALL2) | |
49 | + | |
50 | +/* Tmeperature threshold values for various thermal events */ | |
51 | +struct temperature_params { | |
52 | + /* minimum value in temperature code range */ | |
53 | + unsigned int min_val; | |
54 | + /* maximum value in temperature code range */ | |
55 | + unsigned int max_val; | |
56 | + /* temperature threshold to start warning */ | |
57 | + unsigned int start_warning; | |
58 | + /* temperature threshold CPU tripping */ | |
59 | + unsigned int start_tripping; | |
60 | + /* temperature threshold for HW tripping */ | |
61 | + unsigned int hardware_tripping; | |
62 | +}; | |
63 | + | |
64 | +/* Pre-defined values and thresholds for calibration of current temperature */ | |
65 | +struct tmu_data { | |
66 | + /* pre-defined temperature thresholds */ | |
67 | + struct temperature_params ts; | |
68 | + /* pre-defined efuse range minimum value */ | |
69 | + unsigned int efuse_min_value; | |
70 | + /* pre-defined efuse value for temperature calibration */ | |
71 | + unsigned int efuse_value; | |
72 | + /* pre-defined efuse range maximum value */ | |
73 | + unsigned int efuse_max_value; | |
74 | + /* current temperature sensing slope */ | |
75 | + unsigned int slope; | |
76 | +}; | |
77 | + | |
78 | +/* TMU device specific details and status */ | |
79 | +struct tmu_info { | |
80 | + /* base Address for the TMU */ | |
81 | + unsigned tmu_base; | |
82 | + /* pre-defined values for calibration and thresholds */ | |
83 | + struct tmu_data data; | |
84 | + /* value required for triminfo_25 calibration */ | |
85 | + unsigned int te1; | |
86 | + /* value required for triminfo_85 calibration */ | |
87 | + unsigned int te2; | |
88 | + /* Value for measured data calibration */ | |
89 | + int dc_value; | |
90 | + /* enum value indicating status of the TMU */ | |
91 | + int tmu_state; | |
92 | +}; | |
93 | + | |
94 | +/* Global struct tmu_info variable to store init values */ | |
95 | +static struct tmu_info gbl_info; | |
96 | + | |
97 | +/* | |
98 | + * Get current temperature code from register, | |
99 | + * then calculate and calibrate it's value | |
100 | + * in degree celsius. | |
101 | + * | |
102 | + * @return current temperature of the chip as sensed by TMU | |
103 | + */ | |
104 | +static int get_cur_temp(struct tmu_info *info) | |
105 | +{ | |
106 | + int cur_temp; | |
107 | + struct exynos5_tmu_reg *reg = (struct exynos5_tmu_reg *)info->tmu_base; | |
108 | + | |
109 | + /* | |
110 | + * Temperature code range between min 25 and max 125. | |
111 | + * May run more than once for first call as initial sensing | |
112 | + * has not yet happened. | |
113 | + */ | |
114 | + do { | |
115 | + cur_temp = readl(®->current_temp) & 0xff; | |
116 | + } while (cur_temp == 0 && info->tmu_state == TMU_STATUS_NORMAL); | |
117 | + | |
118 | + /* Calibrate current temperature */ | |
119 | + cur_temp = cur_temp - info->te1 + info->dc_value; | |
120 | + | |
121 | + return cur_temp; | |
122 | +} | |
123 | + | |
124 | +/* | |
125 | + * Monitors status of the TMU device and exynos temperature | |
126 | + * | |
127 | + * @param temp pointer to the current temperature value | |
128 | + * @return enum tmu_status_t value, code indicating event to execute | |
129 | + */ | |
130 | +enum tmu_status_t tmu_monitor(int *temp) | |
131 | +{ | |
132 | + int cur_temp; | |
133 | + struct tmu_data *data = &gbl_info.data; | |
134 | + | |
135 | + if (gbl_info.tmu_state == TMU_STATUS_INIT) | |
136 | + return TMU_STATUS_INIT; | |
137 | + | |
138 | + /* Read current temperature of the SOC */ | |
139 | + cur_temp = get_cur_temp(&gbl_info); | |
140 | + *temp = cur_temp; | |
141 | + | |
142 | + /* Temperature code lies between min 25 and max 125 */ | |
143 | + if (cur_temp >= data->ts.start_tripping && | |
144 | + cur_temp <= data->ts.max_val) { | |
145 | + return TMU_STATUS_TRIPPED; | |
146 | + } else if (cur_temp >= data->ts.start_warning) { | |
147 | + return TMU_STATUS_WARNING; | |
148 | + } else if (cur_temp < data->ts.start_warning && | |
149 | + cur_temp >= data->ts.min_val) { | |
150 | + return TMU_STATUS_NORMAL; | |
151 | + } else { | |
152 | + /* Temperature code does not lie between min 25 and max 125 */ | |
153 | + gbl_info.tmu_state = TMU_STATUS_INIT; | |
154 | + debug("EXYNOS_TMU: Thermal reading failed\n"); | |
155 | + return TMU_STATUS_INIT; | |
156 | + } | |
157 | +} | |
158 | + | |
159 | +/* | |
160 | + * Get TMU specific pre-defined values from FDT | |
161 | + * | |
162 | + * @param info pointer to the tmu_info struct | |
163 | + * @param blob FDT blob | |
164 | + * @return int value, 0 for success | |
165 | + */ | |
166 | +static int get_tmu_fdt_values(struct tmu_info *info, const void *blob) | |
167 | +{ | |
168 | +#ifdef CONFIG_OF_CONTROL | |
169 | + int node; | |
170 | + int error = 0; | |
171 | + | |
172 | + /* Get the node from FDT for TMU */ | |
173 | + node = fdtdec_next_compatible(blob, 0, | |
174 | + COMPAT_SAMSUNG_EXYNOS_TMU); | |
175 | + if (node < 0) { | |
176 | + debug("EXYNOS_TMU: No node for tmu in device tree\n"); | |
177 | + return -1; | |
178 | + } | |
179 | + | |
180 | + /* | |
181 | + * Get the pre-defined TMU specific values from FDT. | |
182 | + * All of these are expected to be correct otherwise | |
183 | + * miscalculation of register values in tmu_setup_parameters | |
184 | + * may result in misleading current temperature. | |
185 | + */ | |
186 | + info->tmu_base = fdtdec_get_addr(blob, node, "reg"); | |
187 | + if (info->tmu_base == FDT_ADDR_T_NONE) { | |
188 | + debug("%s: Missing tmu-base\n", __func__); | |
189 | + return -1; | |
190 | + } | |
191 | + info->data.ts.min_val = fdtdec_get_int(blob, | |
192 | + node, "samsung,min-temp", -1); | |
193 | + error |= info->data.ts.min_val; | |
194 | + info->data.ts.max_val = fdtdec_get_int(blob, | |
195 | + node, "samsung,max-temp", -1); | |
196 | + error |= info->data.ts.max_val; | |
197 | + info->data.ts.start_warning = fdtdec_get_int(blob, | |
198 | + node, "samsung,start-warning", -1); | |
199 | + error |= info->data.ts.start_warning; | |
200 | + info->data.ts.start_tripping = fdtdec_get_int(blob, | |
201 | + node, "samsung,start-tripping", -1); | |
202 | + error |= info->data.ts.start_tripping; | |
203 | + info->data.ts.hardware_tripping = fdtdec_get_int(blob, | |
204 | + node, "samsung,hw-tripping", -1); | |
205 | + error |= info->data.ts.hardware_tripping; | |
206 | + info->data.efuse_min_value = fdtdec_get_int(blob, | |
207 | + node, "samsung,efuse-min-value", -1); | |
208 | + error |= info->data.efuse_min_value; | |
209 | + info->data.efuse_value = fdtdec_get_int(blob, | |
210 | + node, "samsung,efuse-value", -1); | |
211 | + error |= info->data.efuse_value; | |
212 | + info->data.efuse_max_value = fdtdec_get_int(blob, | |
213 | + node, "samsung,efuse-max-value", -1); | |
214 | + error |= info->data.efuse_max_value; | |
215 | + info->data.slope = fdtdec_get_int(blob, | |
216 | + node, "samsung,slope", -1); | |
217 | + error |= info->data.slope; | |
218 | + info->dc_value = fdtdec_get_int(blob, | |
219 | + node, "samsung,dc-value", -1); | |
220 | + error |= info->dc_value; | |
221 | + | |
222 | + if (error == -1) { | |
223 | + debug("fail to get tmu node properties\n"); | |
224 | + return -1; | |
225 | + } | |
226 | +#endif | |
227 | + | |
228 | + return 0; | |
229 | +} | |
230 | + | |
231 | +/* | |
232 | + * Calibrate and calculate threshold values and | |
233 | + * enable interrupt levels | |
234 | + * | |
235 | + * @param info pointer to the tmu_info struct | |
236 | + */ | |
237 | +static void tmu_setup_parameters(struct tmu_info *info) | |
238 | +{ | |
239 | + unsigned int te_code, con; | |
240 | + unsigned int warning_code, trip_code, hwtrip_code; | |
241 | + unsigned int cooling_temp; | |
242 | + unsigned int rising_value; | |
243 | + struct tmu_data *data = &info->data; | |
244 | + struct exynos5_tmu_reg *reg = (struct exynos5_tmu_reg *)info->tmu_base; | |
245 | + | |
246 | + /* Must reload for reading efuse value from triminfo register */ | |
247 | + writel(TRIMINFO_RELOAD, ®->triminfo_control); | |
248 | + | |
249 | + /* Get the compensation parameter */ | |
250 | + te_code = readl(®->triminfo); | |
251 | + info->te1 = te_code & TRIM_INFO_MASK; | |
252 | + info->te2 = ((te_code >> 8) & TRIM_INFO_MASK); | |
253 | + | |
254 | + if ((data->efuse_min_value > info->te1) || | |
255 | + (info->te1 > data->efuse_max_value) | |
256 | + || (info->te2 != 0)) | |
257 | + info->te1 = data->efuse_value; | |
258 | + | |
259 | + /* Get RISING & FALLING Threshold value */ | |
260 | + warning_code = data->ts.start_warning | |
261 | + + info->te1 - info->dc_value; | |
262 | + trip_code = data->ts.start_tripping | |
263 | + + info->te1 - info->dc_value; | |
264 | + hwtrip_code = data->ts.hardware_tripping | |
265 | + + info->te1 - info->dc_value; | |
266 | + | |
267 | + cooling_temp = 0; | |
268 | + | |
269 | + rising_value = ((warning_code << 8) | | |
270 | + (trip_code << 16) | | |
271 | + (hwtrip_code << 24)); | |
272 | + | |
273 | + /* Set interrupt level */ | |
274 | + writel(rising_value, ®->threshold_temp_rise); | |
275 | + writel(cooling_temp, ®->threshold_temp_fall); | |
276 | + | |
277 | + /* | |
278 | + * Init TMU control tuning parameters | |
279 | + * [28:24] VREF - Voltage reference | |
280 | + * [15:13] THERM_TRIP_MODE - Tripping mode | |
281 | + * [12] THERM_TRIP_EN - Thermal tripping enable | |
282 | + * [11:8] BUF_SLOPE_SEL - Gain of amplifier | |
283 | + * [6] THERM_TRIP_BY_TQ_EN - Tripping by TQ pin | |
284 | + */ | |
285 | + writel(data->slope, ®->tmu_control); | |
286 | + | |
287 | + writel(INTCLEARALL, ®->intclear); | |
288 | + | |
289 | + /* TMU core enable */ | |
290 | + con = readl(®->tmu_control); | |
291 | + con |= THERM_TRIP_EN | CORE_EN; | |
292 | + | |
293 | + writel(con, ®->tmu_control); | |
294 | + | |
295 | + /* Enable HW thermal trip */ | |
296 | + set_hw_thermal_trip(); | |
297 | + | |
298 | + /* LEV1 LEV2 interrupt enable */ | |
299 | + writel(INTEN_RISE1 | INTEN_RISE2, ®->inten); | |
300 | +} | |
301 | + | |
302 | +/* | |
303 | + * Initialize TMU device | |
304 | + * | |
305 | + * @param blob FDT blob | |
306 | + * @return int value, 0 for success | |
307 | + */ | |
308 | +int tmu_init(const void *blob) | |
309 | +{ | |
310 | + gbl_info.tmu_state = TMU_STATUS_INIT; | |
311 | + if (get_tmu_fdt_values(&gbl_info, blob) < 0) | |
312 | + goto ret; | |
313 | + | |
314 | + tmu_setup_parameters(&gbl_info); | |
315 | + gbl_info.tmu_state = TMU_STATUS_NORMAL; | |
316 | +ret: | |
317 | + | |
318 | + return gbl_info.tmu_state; | |
319 | +} |
drivers/sound/Makefile
drivers/sound/max98095.c
1 | +/* | |
2 | + * max98095.c -- MAX98095 ALSA SoC Audio driver | |
3 | + * | |
4 | + * Copyright 2011 Maxim Integrated Products | |
5 | + * | |
6 | + * Modified for uboot by R. Chandrasekar (rcsekar@samsung.com) | |
7 | + * | |
8 | + * This program is free software; you can redistribute it and/or modify | |
9 | + * it under the terms of the GNU General Public License version 2 as | |
10 | + * published by the Free Software Foundation. | |
11 | + */ | |
12 | +#include <asm/arch/clk.h> | |
13 | +#include <asm/arch/cpu.h> | |
14 | +#include <asm/arch/power.h> | |
15 | +#include <asm/gpio.h> | |
16 | +#include <asm/io.h> | |
17 | +#include <common.h> | |
18 | +#include <div64.h> | |
19 | +#include <fdtdec.h> | |
20 | +#include <i2c.h> | |
21 | +#include <sound.h> | |
22 | +#include "i2s.h" | |
23 | +#include "max98095.h" | |
24 | + | |
25 | +enum max98095_type { | |
26 | + MAX98095, | |
27 | +}; | |
28 | + | |
29 | +struct max98095_priv { | |
30 | + enum max98095_type devtype; | |
31 | + unsigned int sysclk; | |
32 | + unsigned int rate; | |
33 | + unsigned int fmt; | |
34 | +}; | |
35 | + | |
36 | +static struct sound_codec_info g_codec_info; | |
37 | +struct max98095_priv g_max98095_info; | |
38 | +unsigned int g_max98095_i2c_dev_addr; | |
39 | + | |
40 | +/* Index 0 is reserved. */ | |
41 | +int rate_table[] = {0, 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, | |
42 | + 88200, 96000}; | |
43 | + | |
44 | +/* | |
45 | + * Writes value to a device register through i2c | |
46 | + * | |
47 | + * @param reg reg number to be write | |
48 | + * @param data data to be writen to the above registor | |
49 | + * | |
50 | + * @return int value 1 for change, 0 for no change or negative error code. | |
51 | + */ | |
52 | +static int max98095_i2c_write(unsigned int reg, unsigned char data) | |
53 | +{ | |
54 | + debug("%s: Write Addr : 0x%02X, Data : 0x%02X\n", | |
55 | + __func__, reg, data); | |
56 | + return i2c_write(g_max98095_i2c_dev_addr, reg, 1, &data, 1); | |
57 | +} | |
58 | + | |
59 | +/* | |
60 | + * Read a value from a device register through i2c | |
61 | + * | |
62 | + * @param reg reg number to be read | |
63 | + * @param data address of read data to be stored | |
64 | + * | |
65 | + * @return int value 0 for success, -1 in case of error. | |
66 | + */ | |
67 | +static unsigned int max98095_i2c_read(unsigned int reg, unsigned char *data) | |
68 | +{ | |
69 | + int ret; | |
70 | + | |
71 | + ret = i2c_read(g_max98095_i2c_dev_addr, reg, 1, data, 1); | |
72 | + if (ret != 0) { | |
73 | + debug("%s: Error while reading register %#04x\n", | |
74 | + __func__, reg); | |
75 | + return -1; | |
76 | + } | |
77 | + | |
78 | + return 0; | |
79 | +} | |
80 | + | |
81 | +/* | |
82 | + * update device register bits through i2c | |
83 | + * | |
84 | + * @param reg codec register | |
85 | + * @param mask register mask | |
86 | + * @param value new value | |
87 | + * | |
88 | + * @return int value 0 for success, non-zero error code. | |
89 | + */ | |
90 | +static int max98095_update_bits(unsigned int reg, unsigned char mask, | |
91 | + unsigned char value) | |
92 | +{ | |
93 | + int change, ret = 0; | |
94 | + unsigned char old, new; | |
95 | + | |
96 | + if (max98095_i2c_read(reg, &old) != 0) | |
97 | + return -1; | |
98 | + new = (old & ~mask) | (value & mask); | |
99 | + change = (old != new) ? 1 : 0; | |
100 | + if (change) | |
101 | + ret = max98095_i2c_write(reg, new); | |
102 | + if (ret < 0) | |
103 | + return ret; | |
104 | + | |
105 | + return change; | |
106 | +} | |
107 | + | |
108 | +/* | |
109 | + * codec mclk clock divider coefficients based on sampling rate | |
110 | + * | |
111 | + * @param rate sampling rate | |
112 | + * @param value address of indexvalue to be stored | |
113 | + * | |
114 | + * @return 0 for success or negative error code. | |
115 | + */ | |
116 | +static int rate_value(int rate, u8 *value) | |
117 | +{ | |
118 | + int i; | |
119 | + | |
120 | + for (i = 1; i < ARRAY_SIZE(rate_table); i++) { | |
121 | + if (rate_table[i] >= rate) { | |
122 | + *value = i; | |
123 | + return 0; | |
124 | + } | |
125 | + } | |
126 | + *value = 1; | |
127 | + | |
128 | + return -1; | |
129 | +} | |
130 | + | |
131 | +/* | |
132 | + * Sets hw params for max98095 | |
133 | + * | |
134 | + * @param max98095 max98095 information pointer | |
135 | + * @param rate Sampling rate | |
136 | + * @param bits_per_sample Bits per sample | |
137 | + * | |
138 | + * @return -1 for error and 0 Success. | |
139 | + */ | |
140 | +static int max98095_hw_params(struct max98095_priv *max98095, | |
141 | + unsigned int rate, unsigned int bits_per_sample) | |
142 | +{ | |
143 | + u8 regval; | |
144 | + int error; | |
145 | + | |
146 | + switch (bits_per_sample) { | |
147 | + case 16: | |
148 | + error = max98095_update_bits(M98095_034_DAI2_FORMAT, | |
149 | + M98095_DAI_WS, 0); | |
150 | + break; | |
151 | + case 24: | |
152 | + error = max98095_update_bits(M98095_034_DAI2_FORMAT, | |
153 | + M98095_DAI_WS, M98095_DAI_WS); | |
154 | + break; | |
155 | + default: | |
156 | + debug("%s: Illegal bits per sample %d.\n", | |
157 | + __func__, bits_per_sample); | |
158 | + return -1; | |
159 | + } | |
160 | + | |
161 | + if (rate_value(rate, ®val)) { | |
162 | + debug("%s: Failed to set sample rate to %d.\n", | |
163 | + __func__, rate); | |
164 | + return -1; | |
165 | + } | |
166 | + max98095->rate = rate; | |
167 | + | |
168 | + error |= max98095_update_bits(M98095_031_DAI2_CLKMODE, | |
169 | + M98095_CLKMODE_MASK, regval); | |
170 | + | |
171 | + /* Update sample rate mode */ | |
172 | + if (rate < 50000) | |
173 | + error |= max98095_update_bits(M98095_038_DAI2_FILTERS, | |
174 | + M98095_DAI_DHF, 0); | |
175 | + else | |
176 | + error |= max98095_update_bits(M98095_038_DAI2_FILTERS, | |
177 | + M98095_DAI_DHF, M98095_DAI_DHF); | |
178 | + | |
179 | + if (error < 0) { | |
180 | + debug("%s: Error setting hardware params.\n", __func__); | |
181 | + return -1; | |
182 | + } | |
183 | + | |
184 | + return 0; | |
185 | +} | |
186 | + | |
187 | +/* | |
188 | + * Configures Audio interface system clock for the given frequency | |
189 | + * | |
190 | + * @param max98095 max98095 information | |
191 | + * @param freq Sampling frequency in Hz | |
192 | + * | |
193 | + * @return -1 for error and 0 success. | |
194 | + */ | |
195 | +static int max98095_set_sysclk(struct max98095_priv *max98095, | |
196 | + unsigned int freq) | |
197 | +{ | |
198 | + int error = 0; | |
199 | + | |
200 | + /* Requested clock frequency is already setup */ | |
201 | + if (freq == max98095->sysclk) | |
202 | + return 0; | |
203 | + | |
204 | + /* Setup clocks for slave mode, and using the PLL | |
205 | + * PSCLK = 0x01 (when master clk is 10MHz to 20MHz) | |
206 | + * 0x02 (when master clk is 20MHz to 40MHz).. | |
207 | + * 0x03 (when master clk is 40MHz to 60MHz).. | |
208 | + */ | |
209 | + if ((freq >= 10000000) && (freq < 20000000)) { | |
210 | + error = max98095_i2c_write(M98095_026_SYS_CLK, 0x10); | |
211 | + } else if ((freq >= 20000000) && (freq < 40000000)) { | |
212 | + error = max98095_i2c_write(M98095_026_SYS_CLK, 0x20); | |
213 | + } else if ((freq >= 40000000) && (freq < 60000000)) { | |
214 | + error = max98095_i2c_write(M98095_026_SYS_CLK, 0x30); | |
215 | + } else { | |
216 | + debug("%s: Invalid master clock frequency\n", __func__); | |
217 | + return -1; | |
218 | + } | |
219 | + | |
220 | + debug("%s: Clock at %uHz\n", __func__, freq); | |
221 | + | |
222 | + if (error < 0) | |
223 | + return -1; | |
224 | + | |
225 | + max98095->sysclk = freq; | |
226 | + return 0; | |
227 | +} | |
228 | + | |
229 | +/* | |
230 | + * Sets Max98095 I2S format | |
231 | + * | |
232 | + * @param max98095 max98095 information | |
233 | + * @param fmt i2S format - supports a subset of the options defined | |
234 | + * in i2s.h. | |
235 | + * | |
236 | + * @return -1 for error and 0 Success. | |
237 | + */ | |
238 | +static int max98095_set_fmt(struct max98095_priv *max98095, int fmt) | |
239 | +{ | |
240 | + u8 regval = 0; | |
241 | + int error = 0; | |
242 | + | |
243 | + if (fmt == max98095->fmt) | |
244 | + return 0; | |
245 | + | |
246 | + max98095->fmt = fmt; | |
247 | + | |
248 | + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | |
249 | + case SND_SOC_DAIFMT_CBS_CFS: | |
250 | + /* Slave mode PLL */ | |
251 | + error |= max98095_i2c_write(M98095_032_DAI2_CLKCFG_HI, | |
252 | + 0x80); | |
253 | + error |= max98095_i2c_write(M98095_033_DAI2_CLKCFG_LO, | |
254 | + 0x00); | |
255 | + break; | |
256 | + case SND_SOC_DAIFMT_CBM_CFM: | |
257 | + /* Set to master mode */ | |
258 | + regval |= M98095_DAI_MAS; | |
259 | + break; | |
260 | + case SND_SOC_DAIFMT_CBS_CFM: | |
261 | + case SND_SOC_DAIFMT_CBM_CFS: | |
262 | + default: | |
263 | + debug("%s: Clock mode unsupported\n", __func__); | |
264 | + return -1; | |
265 | + } | |
266 | + | |
267 | + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | |
268 | + case SND_SOC_DAIFMT_I2S: | |
269 | + regval |= M98095_DAI_DLY; | |
270 | + break; | |
271 | + case SND_SOC_DAIFMT_LEFT_J: | |
272 | + break; | |
273 | + default: | |
274 | + debug("%s: Unrecognized format.\n", __func__); | |
275 | + return -1; | |
276 | + } | |
277 | + | |
278 | + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | |
279 | + case SND_SOC_DAIFMT_NB_NF: | |
280 | + break; | |
281 | + case SND_SOC_DAIFMT_NB_IF: | |
282 | + regval |= M98095_DAI_WCI; | |
283 | + break; | |
284 | + case SND_SOC_DAIFMT_IB_NF: | |
285 | + regval |= M98095_DAI_BCI; | |
286 | + break; | |
287 | + case SND_SOC_DAIFMT_IB_IF: | |
288 | + regval |= M98095_DAI_BCI | M98095_DAI_WCI; | |
289 | + break; | |
290 | + default: | |
291 | + debug("%s: Unrecognized inversion settings.\n", __func__); | |
292 | + return -1; | |
293 | + } | |
294 | + | |
295 | + error |= max98095_update_bits(M98095_034_DAI2_FORMAT, | |
296 | + M98095_DAI_MAS | M98095_DAI_DLY | M98095_DAI_BCI | | |
297 | + M98095_DAI_WCI, regval); | |
298 | + | |
299 | + error |= max98095_i2c_write(M98095_035_DAI2_CLOCK, | |
300 | + M98095_DAI_BSEL64); | |
301 | + | |
302 | + if (error < 0) { | |
303 | + debug("%s: Error setting i2s format.\n", __func__); | |
304 | + return -1; | |
305 | + } | |
306 | + | |
307 | + return 0; | |
308 | +} | |
309 | + | |
310 | +/* | |
311 | + * resets the audio codec | |
312 | + * | |
313 | + * @return -1 for error and 0 success. | |
314 | + */ | |
315 | +static int max98095_reset(void) | |
316 | +{ | |
317 | + int i, ret; | |
318 | + | |
319 | + /* | |
320 | + * Gracefully reset the DSP core and the codec hardware in a proper | |
321 | + * sequence. | |
322 | + */ | |
323 | + ret = max98095_i2c_write(M98095_00F_HOST_CFG, 0); | |
324 | + if (ret != 0) { | |
325 | + debug("%s: Failed to reset DSP: %d\n", __func__, ret); | |
326 | + return ret; | |
327 | + } | |
328 | + | |
329 | + ret = max98095_i2c_write(M98095_097_PWR_SYS, 0); | |
330 | + if (ret != 0) { | |
331 | + debug("%s: Failed to reset codec: %d\n", __func__, ret); | |
332 | + return ret; | |
333 | + } | |
334 | + | |
335 | + /* | |
336 | + * Reset to hardware default for registers, as there is not a soft | |
337 | + * reset hardware control register. | |
338 | + */ | |
339 | + for (i = M98095_010_HOST_INT_CFG; i < M98095_REG_MAX_CACHED; i++) { | |
340 | + ret = max98095_i2c_write(i, 0); | |
341 | + if (ret < 0) { | |
342 | + debug("%s: Failed to reset: %d\n", __func__, ret); | |
343 | + return ret; | |
344 | + } | |
345 | + } | |
346 | + | |
347 | + return 0; | |
348 | +} | |
349 | + | |
350 | +/* | |
351 | + * Intialise max98095 codec device | |
352 | + * | |
353 | + * @param max98095 max98095 information | |
354 | + * | |
355 | + * @returns -1 for error and 0 Success. | |
356 | + */ | |
357 | +static int max98095_device_init(struct max98095_priv *max98095) | |
358 | +{ | |
359 | + unsigned char id; | |
360 | + int error = 0; | |
361 | + | |
362 | + /* reset the codec, the DSP core, and disable all interrupts */ | |
363 | + error = max98095_reset(); | |
364 | + if (error != 0) { | |
365 | + debug("Reset\n"); | |
366 | + return error; | |
367 | + } | |
368 | + | |
369 | + /* initialize private data */ | |
370 | + max98095->sysclk = -1U; | |
371 | + max98095->rate = -1U; | |
372 | + max98095->fmt = -1U; | |
373 | + | |
374 | + error = max98095_i2c_read(M98095_0FF_REV_ID, &id); | |
375 | + if (error < 0) { | |
376 | + debug("%s: Failure reading hardware revision: %d\n", | |
377 | + __func__, id); | |
378 | + goto err_access; | |
379 | + } | |
380 | + debug("%s: Hardware revision: %c\n", __func__, (id - 0x40) + 'A'); | |
381 | + | |
382 | + error |= max98095_i2c_write(M98095_097_PWR_SYS, M98095_PWRSV); | |
383 | + | |
384 | + /* | |
385 | + * initialize registers to hardware default configuring audio | |
386 | + * interface2 to DAC | |
387 | + */ | |
388 | + error |= max98095_i2c_write(M98095_048_MIX_DAC_LR, | |
389 | + M98095_DAI2M_TO_DACL|M98095_DAI2M_TO_DACR); | |
390 | + | |
391 | + error |= max98095_i2c_write(M98095_092_PWR_EN_OUT, | |
392 | + M98095_SPK_SPREADSPECTRUM); | |
393 | + error |= max98095_i2c_write(M98095_045_CFG_DSP, M98095_DSPNORMAL); | |
394 | + error |= max98095_i2c_write(M98095_04E_CFG_HP, M98095_HPNORMAL); | |
395 | + | |
396 | + error |= max98095_i2c_write(M98095_02C_DAI1_IOCFG, | |
397 | + M98095_S1NORMAL|M98095_SDATA); | |
398 | + | |
399 | + error |= max98095_i2c_write(M98095_036_DAI2_IOCFG, | |
400 | + M98095_S2NORMAL|M98095_SDATA); | |
401 | + | |
402 | + error |= max98095_i2c_write(M98095_040_DAI3_IOCFG, | |
403 | + M98095_S3NORMAL|M98095_SDATA); | |
404 | + | |
405 | + /* take the codec out of the shut down */ | |
406 | + error |= max98095_update_bits(M98095_097_PWR_SYS, M98095_SHDNRUN, | |
407 | + M98095_SHDNRUN); | |
408 | + /* route DACL and DACR output to HO and Spekers */ | |
409 | + error |= max98095_i2c_write(M98095_050_MIX_SPK_LEFT, 0x01); /* DACL */ | |
410 | + error |= max98095_i2c_write(M98095_051_MIX_SPK_RIGHT, 0x01);/* DACR */ | |
411 | + error |= max98095_i2c_write(M98095_04C_MIX_HP_LEFT, 0x01); /* DACL */ | |
412 | + error |= max98095_i2c_write(M98095_04D_MIX_HP_RIGHT, 0x01); /* DACR */ | |
413 | + | |
414 | + /* power Enable */ | |
415 | + error |= max98095_i2c_write(M98095_091_PWR_EN_OUT, 0xF3); | |
416 | + | |
417 | + /* set Volume */ | |
418 | + error |= max98095_i2c_write(M98095_064_LVL_HP_L, 15); | |
419 | + error |= max98095_i2c_write(M98095_065_LVL_HP_R, 15); | |
420 | + error |= max98095_i2c_write(M98095_067_LVL_SPK_L, 16); | |
421 | + error |= max98095_i2c_write(M98095_068_LVL_SPK_R, 16); | |
422 | + | |
423 | + /* Enable DAIs */ | |
424 | + error |= max98095_i2c_write(M98095_093_BIAS_CTRL, 0x30); | |
425 | + error |= max98095_i2c_write(M98095_096_PWR_DAC_CK, 0x07); | |
426 | + | |
427 | +err_access: | |
428 | + if (error < 0) | |
429 | + return -1; | |
430 | + | |
431 | + return 0; | |
432 | +} | |
433 | + | |
434 | +static int max98095_do_init(struct sound_codec_info *pcodec_info, | |
435 | + int sampling_rate, int mclk_freq, | |
436 | + int bits_per_sample) | |
437 | +{ | |
438 | + int ret = 0; | |
439 | + | |
440 | + /* Enable codec clock */ | |
441 | + set_xclkout(); | |
442 | + | |
443 | + /* shift the device address by 1 for 7 bit addressing */ | |
444 | + g_max98095_i2c_dev_addr = pcodec_info->i2c_dev_addr >> 1; | |
445 | + | |
446 | + if (pcodec_info->codec_type == CODEC_MAX_98095) | |
447 | + g_max98095_info.devtype = MAX98095; | |
448 | + else { | |
449 | + debug("%s: Codec id [%d] not defined\n", __func__, | |
450 | + pcodec_info->codec_type); | |
451 | + return -1; | |
452 | + } | |
453 | + | |
454 | + ret = max98095_device_init(&g_max98095_info); | |
455 | + if (ret < 0) { | |
456 | + debug("%s: max98095 codec chip init failed\n", __func__); | |
457 | + return ret; | |
458 | + } | |
459 | + | |
460 | + ret = max98095_set_sysclk(&g_max98095_info, mclk_freq); | |
461 | + if (ret < 0) { | |
462 | + debug("%s: max98095 codec set sys clock failed\n", __func__); | |
463 | + return ret; | |
464 | + } | |
465 | + | |
466 | + ret = max98095_hw_params(&g_max98095_info, sampling_rate, | |
467 | + bits_per_sample); | |
468 | + | |
469 | + if (ret == 0) { | |
470 | + ret = max98095_set_fmt(&g_max98095_info, | |
471 | + SND_SOC_DAIFMT_I2S | | |
472 | + SND_SOC_DAIFMT_NB_NF | | |
473 | + SND_SOC_DAIFMT_CBS_CFS); | |
474 | + } | |
475 | + | |
476 | + return ret; | |
477 | +} | |
478 | + | |
479 | +static int get_max98095_codec_values(struct sound_codec_info *pcodec_info, | |
480 | + const void *blob) | |
481 | +{ | |
482 | + int error = 0; | |
483 | +#ifdef CONFIG_OF_CONTROL | |
484 | + enum fdt_compat_id compat; | |
485 | + int node; | |
486 | + int parent; | |
487 | + | |
488 | + /* Get the node from FDT for codec */ | |
489 | + node = fdtdec_next_compatible(blob, 0, COMPAT_MAXIM_98095_CODEC); | |
490 | + if (node <= 0) { | |
491 | + debug("EXYNOS_SOUND: No node for codec in device tree\n"); | |
492 | + debug("node = %d\n", node); | |
493 | + return -1; | |
494 | + } | |
495 | + | |
496 | + parent = fdt_parent_offset(blob, node); | |
497 | + if (parent < 0) { | |
498 | + debug("%s: Cannot find node parent\n", __func__); | |
499 | + return -1; | |
500 | + } | |
501 | + | |
502 | + compat = fdtdec_lookup(blob, parent); | |
503 | + switch (compat) { | |
504 | + case COMPAT_SAMSUNG_S3C2440_I2C: | |
505 | + pcodec_info->i2c_bus = i2c_get_bus_num_fdt(parent); | |
506 | + error |= pcodec_info->i2c_bus; | |
507 | + debug("i2c bus = %d\n", pcodec_info->i2c_bus); | |
508 | + pcodec_info->i2c_dev_addr = fdtdec_get_int(blob, node, | |
509 | + "reg", 0); | |
510 | + error |= pcodec_info->i2c_dev_addr; | |
511 | + debug("i2c dev addr = %x\n", pcodec_info->i2c_dev_addr); | |
512 | + break; | |
513 | + default: | |
514 | + debug("%s: Unknown compat id %d\n", __func__, compat); | |
515 | + return -1; | |
516 | + } | |
517 | +#else | |
518 | + pcodec_info->i2c_bus = AUDIO_I2C_BUS; | |
519 | + pcodec_info->i2c_dev_addr = AUDIO_I2C_REG; | |
520 | + debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr); | |
521 | +#endif | |
522 | + pcodec_info->codec_type = CODEC_MAX_98095; | |
523 | + if (error == -1) { | |
524 | + debug("fail to get max98095 codec node properties\n"); | |
525 | + return -1; | |
526 | + } | |
527 | + | |
528 | + return 0; | |
529 | +} | |
530 | + | |
531 | +/* max98095 Device Initialisation */ | |
532 | +int max98095_init(const void *blob, int sampling_rate, int mclk_freq, | |
533 | + int bits_per_sample) | |
534 | +{ | |
535 | + int ret; | |
536 | + int old_bus = i2c_get_bus_num(); | |
537 | + struct sound_codec_info *pcodec_info = &g_codec_info; | |
538 | + | |
539 | + if (get_max98095_codec_values(pcodec_info, blob) < 0) { | |
540 | + debug("FDT Codec values failed\n"); | |
541 | + return -1; | |
542 | + } | |
543 | + | |
544 | + i2c_set_bus_num(pcodec_info->i2c_bus); | |
545 | + ret = max98095_do_init(pcodec_info, sampling_rate, mclk_freq, | |
546 | + bits_per_sample); | |
547 | + i2c_set_bus_num(old_bus); | |
548 | + | |
549 | + return ret; | |
550 | +} |
drivers/sound/max98095.h
1 | +/* | |
2 | + * max98095.h -- MAX98095 ALSA SoC Audio driver | |
3 | + * | |
4 | + * Copyright 2011 Maxim Integrated Products | |
5 | + * | |
6 | + * This program is free software; you can redistribute it and/or modify | |
7 | + * it under the terms of the GNU General Public License version 2 as | |
8 | + * published by the Free Software Foundation. | |
9 | + */ | |
10 | + | |
11 | +#ifndef _MAX98095_H | |
12 | +#define _MAX98095_H | |
13 | + | |
14 | +/* | |
15 | + * MAX98095 Registers Definition | |
16 | + */ | |
17 | + | |
18 | +#define M98095_000_HOST_DATA 0x00 | |
19 | +#define M98095_001_HOST_INT_STS 0x01 | |
20 | +#define M98095_002_HOST_RSP_STS 0x02 | |
21 | +#define M98095_003_HOST_CMD_STS 0x03 | |
22 | +#define M98095_004_CODEC_STS 0x04 | |
23 | +#define M98095_005_DAI1_ALC_STS 0x05 | |
24 | +#define M98095_006_DAI2_ALC_STS 0x06 | |
25 | +#define M98095_007_JACK_AUTO_STS 0x07 | |
26 | +#define M98095_008_JACK_MANUAL_STS 0x08 | |
27 | +#define M98095_009_JACK_VBAT_STS 0x09 | |
28 | +#define M98095_00A_ACC_ADC_STS 0x0A | |
29 | +#define M98095_00B_MIC_NG_AGC_STS 0x0B | |
30 | +#define M98095_00C_SPK_L_VOLT_STS 0x0C | |
31 | +#define M98095_00D_SPK_R_VOLT_STS 0x0D | |
32 | +#define M98095_00E_TEMP_SENSOR_STS 0x0E | |
33 | +#define M98095_00F_HOST_CFG 0x0F | |
34 | +#define M98095_010_HOST_INT_CFG 0x10 | |
35 | +#define M98095_011_HOST_INT_EN 0x11 | |
36 | +#define M98095_012_CODEC_INT_EN 0x12 | |
37 | +#define M98095_013_JACK_INT_EN 0x13 | |
38 | +#define M98095_014_JACK_INT_EN 0x14 | |
39 | +#define M98095_015_DEC 0x15 | |
40 | +#define M98095_016_RESERVED 0x16 | |
41 | +#define M98095_017_RESERVED 0x17 | |
42 | +#define M98095_018_KEYCODE3 0x18 | |
43 | +#define M98095_019_KEYCODE2 0x19 | |
44 | +#define M98095_01A_KEYCODE1 0x1A | |
45 | +#define M98095_01B_KEYCODE0 0x1B | |
46 | +#define M98095_01C_OEMCODE1 0x1C | |
47 | +#define M98095_01D_OEMCODE0 0x1D | |
48 | +#define M98095_01E_XCFG1 0x1E | |
49 | +#define M98095_01F_XCFG2 0x1F | |
50 | +#define M98095_020_XCFG3 0x20 | |
51 | +#define M98095_021_XCFG4 0x21 | |
52 | +#define M98095_022_XCFG5 0x22 | |
53 | +#define M98095_023_XCFG6 0x23 | |
54 | +#define M98095_024_XGPIO 0x24 | |
55 | +#define M98095_025_XCLKCFG 0x25 | |
56 | +#define M98095_026_SYS_CLK 0x26 | |
57 | +#define M98095_027_DAI1_CLKMODE 0x27 | |
58 | +#define M98095_028_DAI1_CLKCFG_HI 0x28 | |
59 | +#define M98095_029_DAI1_CLKCFG_LO 0x29 | |
60 | +#define M98095_02A_DAI1_FORMAT 0x2A | |
61 | +#define M98095_02B_DAI1_CLOCK 0x2B | |
62 | +#define M98095_02C_DAI1_IOCFG 0x2C | |
63 | +#define M98095_02D_DAI1_TDM 0x2D | |
64 | +#define M98095_02E_DAI1_FILTERS 0x2E | |
65 | +#define M98095_02F_DAI1_LVL1 0x2F | |
66 | +#define M98095_030_DAI1_LVL2 0x30 | |
67 | +#define M98095_031_DAI2_CLKMODE 0x31 | |
68 | +#define M98095_032_DAI2_CLKCFG_HI 0x32 | |
69 | +#define M98095_033_DAI2_CLKCFG_LO 0x33 | |
70 | +#define M98095_034_DAI2_FORMAT 0x34 | |
71 | +#define M98095_035_DAI2_CLOCK 0x35 | |
72 | +#define M98095_036_DAI2_IOCFG 0x36 | |
73 | +#define M98095_037_DAI2_TDM 0x37 | |
74 | +#define M98095_038_DAI2_FILTERS 0x38 | |
75 | +#define M98095_039_DAI2_LVL1 0x39 | |
76 | +#define M98095_03A_DAI2_LVL2 0x3A | |
77 | +#define M98095_03B_DAI3_CLKMODE 0x3B | |
78 | +#define M98095_03C_DAI3_CLKCFG_HI 0x3C | |
79 | +#define M98095_03D_DAI3_CLKCFG_LO 0x3D | |
80 | +#define M98095_03E_DAI3_FORMAT 0x3E | |
81 | +#define M98095_03F_DAI3_CLOCK 0x3F | |
82 | +#define M98095_040_DAI3_IOCFG 0x40 | |
83 | +#define M98095_041_DAI3_TDM 0x41 | |
84 | +#define M98095_042_DAI3_FILTERS 0x42 | |
85 | +#define M98095_043_DAI3_LVL1 0x43 | |
86 | +#define M98095_044_DAI3_LVL2 0x44 | |
87 | +#define M98095_045_CFG_DSP 0x45 | |
88 | +#define M98095_046_DAC_CTRL1 0x46 | |
89 | +#define M98095_047_DAC_CTRL2 0x47 | |
90 | +#define M98095_048_MIX_DAC_LR 0x48 | |
91 | +#define M98095_049_MIX_DAC_M 0x49 | |
92 | +#define M98095_04A_MIX_ADC_LEFT 0x4A | |
93 | +#define M98095_04B_MIX_ADC_RIGHT 0x4B | |
94 | +#define M98095_04C_MIX_HP_LEFT 0x4C | |
95 | +#define M98095_04D_MIX_HP_RIGHT 0x4D | |
96 | +#define M98095_04E_CFG_HP 0x4E | |
97 | +#define M98095_04F_MIX_RCV 0x4F | |
98 | +#define M98095_050_MIX_SPK_LEFT 0x50 | |
99 | +#define M98095_051_MIX_SPK_RIGHT 0x51 | |
100 | +#define M98095_052_MIX_SPK_CFG 0x52 | |
101 | +#define M98095_053_MIX_LINEOUT1 0x53 | |
102 | +#define M98095_054_MIX_LINEOUT2 0x54 | |
103 | +#define M98095_055_MIX_LINEOUT_CFG 0x55 | |
104 | +#define M98095_056_LVL_SIDETONE_DAI12 0x56 | |
105 | +#define M98095_057_LVL_SIDETONE_DAI3 0x57 | |
106 | +#define M98095_058_LVL_DAI1_PLAY 0x58 | |
107 | +#define M98095_059_LVL_DAI1_EQ 0x59 | |
108 | +#define M98095_05A_LVL_DAI2_PLAY 0x5A | |
109 | +#define M98095_05B_LVL_DAI2_EQ 0x5B | |
110 | +#define M98095_05C_LVL_DAI3_PLAY 0x5C | |
111 | +#define M98095_05D_LVL_ADC_L 0x5D | |
112 | +#define M98095_05E_LVL_ADC_R 0x5E | |
113 | +#define M98095_05F_LVL_MIC1 0x5F | |
114 | +#define M98095_060_LVL_MIC2 0x60 | |
115 | +#define M98095_061_LVL_LINEIN 0x61 | |
116 | +#define M98095_062_LVL_LINEOUT1 0x62 | |
117 | +#define M98095_063_LVL_LINEOUT2 0x63 | |
118 | +#define M98095_064_LVL_HP_L 0x64 | |
119 | +#define M98095_065_LVL_HP_R 0x65 | |
120 | +#define M98095_066_LVL_RCV 0x66 | |
121 | +#define M98095_067_LVL_SPK_L 0x67 | |
122 | +#define M98095_068_LVL_SPK_R 0x68 | |
123 | +#define M98095_069_MICAGC_CFG 0x69 | |
124 | +#define M98095_06A_MICAGC_THRESH 0x6A | |
125 | +#define M98095_06B_SPK_NOISEGATE 0x6B | |
126 | +#define M98095_06C_DAI1_ALC1_TIME 0x6C | |
127 | +#define M98095_06D_DAI1_ALC1_COMP 0x6D | |
128 | +#define M98095_06E_DAI1_ALC1_EXPN 0x6E | |
129 | +#define M98095_06F_DAI1_ALC1_GAIN 0x6F | |
130 | +#define M98095_070_DAI1_ALC2_TIME 0x70 | |
131 | +#define M98095_071_DAI1_ALC2_COMP 0x71 | |
132 | +#define M98095_072_DAI1_ALC2_EXPN 0x72 | |
133 | +#define M98095_073_DAI1_ALC2_GAIN 0x73 | |
134 | +#define M98095_074_DAI1_ALC3_TIME 0x74 | |
135 | +#define M98095_075_DAI1_ALC3_COMP 0x75 | |
136 | +#define M98095_076_DAI1_ALC3_EXPN 0x76 | |
137 | +#define M98095_077_DAI1_ALC3_GAIN 0x77 | |
138 | +#define M98095_078_DAI2_ALC1_TIME 0x78 | |
139 | +#define M98095_079_DAI2_ALC1_COMP 0x79 | |
140 | +#define M98095_07A_DAI2_ALC1_EXPN 0x7A | |
141 | +#define M98095_07B_DAI2_ALC1_GAIN 0x7B | |
142 | +#define M98095_07C_DAI2_ALC2_TIME 0x7C | |
143 | +#define M98095_07D_DAI2_ALC2_COMP 0x7D | |
144 | +#define M98095_07E_DAI2_ALC2_EXPN 0x7E | |
145 | +#define M98095_07F_DAI2_ALC2_GAIN 0x7F | |
146 | +#define M98095_080_DAI2_ALC3_TIME 0x80 | |
147 | +#define M98095_081_DAI2_ALC3_COMP 0x81 | |
148 | +#define M98095_082_DAI2_ALC3_EXPN 0x82 | |
149 | +#define M98095_083_DAI2_ALC3_GAIN 0x83 | |
150 | +#define M98095_084_HP_NOISE_GATE 0x84 | |
151 | +#define M98095_085_AUX_ADC 0x85 | |
152 | +#define M98095_086_CFG_LINE 0x86 | |
153 | +#define M98095_087_CFG_MIC 0x87 | |
154 | +#define M98095_088_CFG_LEVEL 0x88 | |
155 | +#define M98095_089_JACK_DET_AUTO 0x89 | |
156 | +#define M98095_08A_JACK_DET_MANUAL 0x8A | |
157 | +#define M98095_08B_JACK_KEYSCAN_DBC 0x8B | |
158 | +#define M98095_08C_JACK_KEYSCAN_DLY 0x8C | |
159 | +#define M98095_08D_JACK_KEY_THRESH 0x8D | |
160 | +#define M98095_08E_JACK_DC_SLEW 0x8E | |
161 | +#define M98095_08F_JACK_TEST_CFG 0x8F | |
162 | +#define M98095_090_PWR_EN_IN 0x90 | |
163 | +#define M98095_091_PWR_EN_OUT 0x91 | |
164 | +#define M98095_092_PWR_EN_OUT 0x92 | |
165 | +#define M98095_093_BIAS_CTRL 0x93 | |
166 | +#define M98095_094_PWR_DAC_21 0x94 | |
167 | +#define M98095_095_PWR_DAC_03 0x95 | |
168 | +#define M98095_096_PWR_DAC_CK 0x96 | |
169 | +#define M98095_097_PWR_SYS 0x97 | |
170 | + | |
171 | +#define M98095_0FF_REV_ID 0xFF | |
172 | + | |
173 | +#define M98095_REG_CNT (0xFF+1) | |
174 | +#define M98095_REG_MAX_CACHED 0X97 | |
175 | + | |
176 | +/* MAX98095 Registers Bit Fields */ | |
177 | + | |
178 | +/* M98095_00F_HOST_CFG */ | |
179 | +#define M98095_SEG (1<<0) | |
180 | +#define M98095_XTEN (1<<1) | |
181 | +#define M98095_MDLLEN (1<<2) | |
182 | + | |
183 | +/* M98095_027_DAI1_CLKMODE, M98095_031_DAI2_CLKMODE, M98095_03B_DAI3_CLKMODE */ | |
184 | +#define M98095_CLKMODE_MASK 0xFF | |
185 | + | |
186 | +/* M98095_02A_DAI1_FORMAT, M98095_034_DAI2_FORMAT, M98095_03E_DAI3_FORMAT */ | |
187 | +#define M98095_DAI_MAS (1<<7) | |
188 | +#define M98095_DAI_WCI (1<<6) | |
189 | +#define M98095_DAI_BCI (1<<5) | |
190 | +#define M98095_DAI_DLY (1<<4) | |
191 | +#define M98095_DAI_TDM (1<<2) | |
192 | +#define M98095_DAI_FSW (1<<1) | |
193 | +#define M98095_DAI_WS (1<<0) | |
194 | + | |
195 | +/* M98095_02B_DAI1_CLOCK, M98095_035_DAI2_CLOCK, M98095_03F_DAI3_CLOCK */ | |
196 | +#define M98095_DAI_BSEL64 (1<<0) | |
197 | +#define M98095_DAI_DOSR_DIV2 (0<<5) | |
198 | +#define M98095_DAI_DOSR_DIV4 (1<<5) | |
199 | + | |
200 | +/* M98095_02C_DAI1_IOCFG, M98095_036_DAI2_IOCFG, M98095_040_DAI3_IOCFG */ | |
201 | +#define M98095_S1NORMAL (1<<6) | |
202 | +#define M98095_S2NORMAL (2<<6) | |
203 | +#define M98095_S3NORMAL (3<<6) | |
204 | +#define M98095_SDATA (3<<0) | |
205 | + | |
206 | +/* M98095_02E_DAI1_FILTERS, M98095_038_DAI2_FILTERS, M98095_042_DAI3_FILTERS */ | |
207 | +#define M98095_DAI_DHF (1<<3) | |
208 | + | |
209 | +/* M98095_045_DSP_CFG */ | |
210 | +#define M98095_DSPNORMAL (5<<4) | |
211 | + | |
212 | +/* M98095_048_MIX_DAC_LR */ | |
213 | +#define M98095_DAI1L_TO_DACR (1<<7) | |
214 | +#define M98095_DAI1R_TO_DACR (1<<6) | |
215 | +#define M98095_DAI2M_TO_DACR (1<<5) | |
216 | +#define M98095_DAI1L_TO_DACL (1<<3) | |
217 | +#define M98095_DAI1R_TO_DACL (1<<2) | |
218 | +#define M98095_DAI2M_TO_DACL (1<<1) | |
219 | +#define M98095_DAI3M_TO_DACL (1<<0) | |
220 | + | |
221 | +/* M98095_049_MIX_DAC_M */ | |
222 | +#define M98095_DAI1L_TO_DACM (1<<3) | |
223 | +#define M98095_DAI1R_TO_DACM (1<<2) | |
224 | +#define M98095_DAI2M_TO_DACM (1<<1) | |
225 | +#define M98095_DAI3M_TO_DACM (1<<0) | |
226 | + | |
227 | +/* M98095_04E_MIX_HP_CFG */ | |
228 | +#define M98095_HPNORMAL (3<<4) | |
229 | + | |
230 | +/* M98095_05F_LVL_MIC1, M98095_060_LVL_MIC2 */ | |
231 | +#define M98095_MICPRE_MASK (3<<5) | |
232 | +#define M98095_MICPRE_SHIFT 5 | |
233 | + | |
234 | +/* M98095_064_LVL_HP_L, M98095_065_LVL_HP_R */ | |
235 | +#define M98095_HP_MUTE (1<<7) | |
236 | + | |
237 | +/* M98095_066_LVL_RCV */ | |
238 | +#define M98095_REC_MUTE (1<<7) | |
239 | + | |
240 | +/* M98095_067_LVL_SPK_L, M98095_068_LVL_SPK_R */ | |
241 | +#define M98095_SP_MUTE (1<<7) | |
242 | + | |
243 | +/* M98095_087_CFG_MIC */ | |
244 | +#define M98095_MICSEL_MASK (3<<0) | |
245 | +#define M98095_DIGMIC_L (1<<2) | |
246 | +#define M98095_DIGMIC_R (1<<3) | |
247 | +#define M98095_DIGMIC2L (1<<4) | |
248 | +#define M98095_DIGMIC2R (1<<5) | |
249 | + | |
250 | +/* M98095_088_CFG_LEVEL */ | |
251 | +#define M98095_VSEN (1<<6) | |
252 | +#define M98095_ZDEN (1<<5) | |
253 | +#define M98095_BQ2EN (1<<3) | |
254 | +#define M98095_BQ1EN (1<<2) | |
255 | +#define M98095_EQ2EN (1<<1) | |
256 | +#define M98095_EQ1EN (1<<0) | |
257 | + | |
258 | +/* M98095_090_PWR_EN_IN */ | |
259 | +#define M98095_INEN (1<<7) | |
260 | +#define M98095_MB2EN (1<<3) | |
261 | +#define M98095_MB1EN (1<<2) | |
262 | +#define M98095_MBEN (3<<2) | |
263 | +#define M98095_ADREN (1<<1) | |
264 | +#define M98095_ADLEN (1<<0) | |
265 | + | |
266 | +/* M98095_091_PWR_EN_OUT */ | |
267 | +#define M98095_HPLEN (1<<7) | |
268 | +#define M98095_HPREN (1<<6) | |
269 | +#define M98095_SPLEN (1<<5) | |
270 | +#define M98095_SPREN (1<<4) | |
271 | +#define M98095_RECEN (1<<3) | |
272 | +#define M98095_DALEN (1<<1) | |
273 | +#define M98095_DAREN (1<<0) | |
274 | + | |
275 | +/* M98095_092_PWR_EN_OUT */ | |
276 | +#define M98095_SPK_FIXEDSPECTRUM (0<<4) | |
277 | +#define M98095_SPK_SPREADSPECTRUM (1<<4) | |
278 | + | |
279 | +/* M98095_097_PWR_SYS */ | |
280 | +#define M98095_SHDNRUN (1<<7) | |
281 | +#define M98095_PERFMODE (1<<3) | |
282 | +#define M98095_HPPLYBACK (1<<2) | |
283 | +#define M98095_PWRSV8K (1<<1) | |
284 | +#define M98095_PWRSV (1<<0) | |
285 | + | |
286 | +#define M98095_COEFS_PER_BAND 5 | |
287 | + | |
288 | +/* Equalizer filter coefficients */ | |
289 | +#define M98095_110_DAI1_EQ_BASE 0x10 | |
290 | +#define M98095_142_DAI2_EQ_BASE 0x42 | |
291 | + | |
292 | +/* Biquad filter coefficients */ | |
293 | +#define M98095_174_DAI1_BQ_BASE 0x74 | |
294 | +#define M98095_17E_DAI2_BQ_BASE 0x7E | |
295 | + | |
296 | +/* function prototype */ | |
297 | + | |
298 | +/* | |
299 | + * intialise max98095 sound codec device for the given configuration | |
300 | + * | |
301 | + * @param blob FDT node for codec values | |
302 | + * @param sampling_rate Sampling rate (Hz) | |
303 | + * @param mclk_freq MCLK Frequency (Hz) | |
304 | + * @param bits_per_sample bits per Sample (must be 16 or 24) | |
305 | + * | |
306 | + * @returns -1 for error and 0 Success. | |
307 | + */ | |
308 | +int max98095_init(const void *blob, int sampling_rate, int mclk_freq, | |
309 | + int bits_per_sample); | |
310 | + | |
311 | +#endif |
drivers/sound/sound.c
... | ... | @@ -31,6 +31,7 @@ |
31 | 31 | #include <sound.h> |
32 | 32 | #include <asm/arch/sound.h> |
33 | 33 | #include "wm8994.h" |
34 | +#include "max98095.h" | |
34 | 35 | |
35 | 36 | /* defines */ |
36 | 37 | #define SOUND_400_HZ 400 |
37 | 38 | |
38 | 39 | |
... | ... | @@ -149,11 +150,15 @@ |
149 | 150 | pi2s_tx->samplingrate, |
150 | 151 | (pi2s_tx->samplingrate * (pi2s_tx->rfs)), |
151 | 152 | pi2s_tx->bitspersample, pi2s_tx->channels); |
153 | + } else if (!strcmp(codectype, "max98095")) { | |
154 | + ret = max98095_init(blob, pi2s_tx->samplingrate, | |
155 | + (pi2s_tx->samplingrate * (pi2s_tx->rfs)), | |
156 | + pi2s_tx->bitspersample); | |
152 | 157 | } else { |
153 | - debug("%s: Unknown code type %s\n", __func__, | |
154 | - codectype); | |
158 | + debug("%s: Unknown codec type %s\n", __func__, codectype); | |
155 | 159 | return -1; |
156 | 160 | } |
161 | + | |
157 | 162 | if (ret) { |
158 | 163 | debug("%s: Codec init failed\n", __func__); |
159 | 164 | return -1; |
include/configs/exynos5250-dt.h
... | ... | @@ -118,6 +118,11 @@ |
118 | 118 | #define CONFIG_BOOTDELAY 3 |
119 | 119 | #define CONFIG_ZERO_BOOTDELAY_CHECK |
120 | 120 | |
121 | +/* Thermal Management Unit */ | |
122 | +#define CONFIG_EXYNOS_TMU | |
123 | +#define CONFIG_CMD_DTT | |
124 | +#define CONFIG_TMU_CMD_DTT | |
125 | + | |
121 | 126 | /* USB */ |
122 | 127 | #define CONFIG_CMD_USB |
123 | 128 | #define CONFIG_USB_EHCI |
... | ... | @@ -297,6 +302,7 @@ |
297 | 302 | #ifdef CONFIG_CMD_SOUND |
298 | 303 | #define CONFIG_SOUND |
299 | 304 | #define CONFIG_I2S |
305 | +#define CONFIG_SOUND_MAX98095 | |
300 | 306 | #define CONFIG_SOUND_WM8994 |
301 | 307 | #endif |
302 | 308 |
include/configs/snow.h
1 | +/* | |
2 | + * Copyright (C) 2013 Samsung Electronics | |
3 | + * | |
4 | + * Configuration settings for the SAMSUNG EXYNOS5 Snow board. | |
5 | + * | |
6 | + * See file CREDITS for list of people who contributed to this | |
7 | + * project. | |
8 | + * | |
9 | + * This program is free software; you can redistribute it and/or | |
10 | + * modify it under the terms of the GNU General Public License as | |
11 | + * published by the Free Software Foundation; either version 2 of | |
12 | + * the License, or (at your option) any later version. | |
13 | + * | |
14 | + * This program is distributed in the hope that it will be useful, | |
15 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | + * GNU General Public License for more details. | |
18 | + * | |
19 | + * You should have received a copy of the GNU General Public License | |
20 | + * along with this program; if not, write to the Free Software | |
21 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
22 | + * MA 02111-1307 USA | |
23 | + */ | |
24 | + | |
25 | +#ifndef __CONFIG_SNOW_H | |
26 | +#define __CONFIG_SNOW_H | |
27 | + | |
28 | +#include <configs/exynos5250-dt.h> | |
29 | + | |
30 | +#undef CONFIG_DEFAULT_DEVICE_TREE | |
31 | +#define CONFIG_DEFAULT_DEVICE_TREE exynos5250-snow | |
32 | + | |
33 | +#endif /* __CONFIG_SNOW_H */ |
include/fdtdec.h
... | ... | @@ -83,7 +83,9 @@ |
83 | 83 | COMPAT_SAMSUNG_EXYNOS_SPI, /* Exynos SPI */ |
84 | 84 | COMPAT_SAMSUNG_EXYNOS_EHCI, /* Exynos EHCI controller */ |
85 | 85 | COMPAT_SAMSUNG_EXYNOS_USB_PHY, /* Exynos phy controller for usb2.0 */ |
86 | + COMPAT_SAMSUNG_EXYNOS_TMU, /* Exynos TMU */ | |
86 | 87 | COMPAT_MAXIM_MAX77686_PMIC, /* MAX77686 PMIC */ |
88 | + COMPAT_MAXIM_98095_CODEC, /* MAX98095 Codec */ | |
87 | 89 | |
88 | 90 | COMPAT_COUNT, |
89 | 91 | }; |
include/power/max77686_pmic.h
... | ... | @@ -155,5 +155,37 @@ |
155 | 155 | EN_LDO = (0x3 << 6), |
156 | 156 | }; |
157 | 157 | |
158 | +/* Buck1 1 volt value */ | |
159 | +#define MAX77686_BUCK1OUT_1V 0x5 | |
160 | +#define MAX77686_BUCK1CTRL_EN (3 << 0) | |
161 | +/* Buck2 1.3 volt value */ | |
162 | +#define MAX77686_BUCK2DVS1_1_3V 0x38 | |
163 | +#define MAX77686_BUCK2CTRL_ON (1 << 4) | |
164 | +/* Buck3 1.0125 volt value */ | |
165 | +#define MAX77686_BUCK3DVS1_1_0125V 0x21 | |
166 | +#define MAX77686_BUCK3CTRL_ON (1 << 4) | |
167 | +/* Buck4 1.2 volt value */ | |
168 | +#define MAX77686_BUCK4DVS1_1_2V 0x30 | |
169 | +#define MAX77686_BUCK4CTRL_ON (1 << 4) | |
170 | +/* LDO2 1.5 volt value */ | |
171 | +#define MAX77686_LD02CTRL1_1_5V 0x1c | |
172 | +/* LDO3 1.8 volt value */ | |
173 | +#define MAX77686_LD03CTRL1_1_8V 0x14 | |
174 | +/* LDO5 1.8 volt value */ | |
175 | +#define MAX77686_LD05CTRL1_1_8V 0x14 | |
176 | +/* LDO10 1.8 volt value */ | |
177 | +#define MAX77686_LD10CTRL1_1_8V 0x14 | |
178 | +/* | |
179 | + * MAX77686_REG_PMIC_32KHZ set to 32KH CP | |
180 | + * output is activated | |
181 | + */ | |
182 | +#define MAX77686_32KHCP_EN (1 << 1) | |
183 | +/* | |
184 | + * MAX77686_REG_PMIC_BBAT set to | |
185 | + * Back up batery charger on and | |
186 | + * limit voltage setting to 3.5v | |
187 | + */ | |
188 | +#define MAX77686_BBCHOSTEN (1 << 0) | |
189 | +#define MAX77686_BBCVS_3_5V (3 << 3) | |
158 | 190 | #endif /* __MAX77686_PMIC_H_ */ |
include/sound.h
include/tmu.h
1 | +/* | |
2 | + * Copyright (c) 2012 Samsung Electronics Co., Ltd. | |
3 | + * http://www.samsung.com | |
4 | + * Akshay Saraswat <akshay.s@samsung.com> | |
5 | + * | |
6 | + * Thermal Management Unit | |
7 | + * | |
8 | + * See file CREDITS for list of people who contributed to this | |
9 | + * project. | |
10 | + * | |
11 | + * This program is free software; you can redistribute it and/or modify | |
12 | + * it under the terms of the GNU General Public License version 2 as | |
13 | + * published by the Free Software Foundation. | |
14 | + * You should have received a copy of the GNU General Public License | |
15 | + * along with this program; if not, write to the Free Software | |
16 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
17 | + * MA 02111-1307 USA | |
18 | + */ | |
19 | + | |
20 | +#ifndef _TMU_H | |
21 | +#define _TMU_H | |
22 | + | |
23 | +enum tmu_status_t { | |
24 | + TMU_STATUS_INIT = -1, | |
25 | + TMU_STATUS_NORMAL = 0, | |
26 | + TMU_STATUS_WARNING, | |
27 | + TMU_STATUS_TRIPPED, | |
28 | +}; | |
29 | + | |
30 | +/* | |
31 | + * Monitors status of the TMU device and exynos temperature | |
32 | + * | |
33 | + * @param temp pointer to the current temperature value | |
34 | + * @return enum tmu_status_t value, code indicating event to execute | |
35 | + * and -1 on error | |
36 | + */ | |
37 | +enum tmu_status_t tmu_monitor(int *temp); | |
38 | + | |
39 | +/* | |
40 | + * Initialize TMU device | |
41 | + * | |
42 | + * @param blob FDT blob | |
43 | + * @return int value, 0 for success | |
44 | + */ | |
45 | +int tmu_init(const void *blob); | |
46 | +#endif /* _THERMAL_H_ */ |
lib/fdtdec.c
... | ... | @@ -58,7 +58,9 @@ |
58 | 58 | COMPAT(SAMSUNG_EXYNOS_SPI, "samsung,exynos-spi"), |
59 | 59 | COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"), |
60 | 60 | COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"), |
61 | + COMPAT(SAMSUNG_EXYNOS_TMU, "samsung,exynos-tmu"), | |
61 | 62 | COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"), |
63 | + COMPAT(MAXIM_98095_CODEC, "maxim,max98095-codec"), | |
62 | 64 | }; |
63 | 65 | |
64 | 66 | const char *fdtdec_get_compatible(enum fdt_compat_id id) |