cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

lcc-mdm9615.c (14225B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
      4 * Copyright (c) BayLibre, SAS.
      5 * Author : Neil Armstrong <narmstrong@baylibre.com>
      6 */
      7
      8#include <linux/kernel.h>
      9#include <linux/bitops.h>
     10#include <linux/err.h>
     11#include <linux/platform_device.h>
     12#include <linux/module.h>
     13#include <linux/of.h>
     14#include <linux/of_device.h>
     15#include <linux/clk-provider.h>
     16#include <linux/regmap.h>
     17
     18#include <dt-bindings/clock/qcom,lcc-mdm9615.h>
     19
     20#include "common.h"
     21#include "clk-regmap.h"
     22#include "clk-pll.h"
     23#include "clk-rcg.h"
     24#include "clk-branch.h"
     25#include "clk-regmap-divider.h"
     26#include "clk-regmap-mux.h"
     27
     28static struct clk_pll pll4 = {
     29	.l_reg = 0x4,
     30	.m_reg = 0x8,
     31	.n_reg = 0xc,
     32	.config_reg = 0x14,
     33	.mode_reg = 0x0,
     34	.status_reg = 0x18,
     35	.status_bit = 16,
     36	.clkr.hw.init = &(struct clk_init_data){
     37		.name = "pll4",
     38		.parent_names = (const char *[]){ "cxo" },
     39		.num_parents = 1,
     40		.ops = &clk_pll_ops,
     41	},
     42};
     43
     44enum {
     45	P_CXO,
     46	P_PLL4,
     47};
     48
     49static const struct parent_map lcc_cxo_pll4_map[] = {
     50	{ P_CXO, 0 },
     51	{ P_PLL4, 2 }
     52};
     53
     54static const char * const lcc_cxo_pll4[] = {
     55	"cxo",
     56	"pll4_vote",
     57};
     58
     59static struct freq_tbl clk_tbl_aif_osr_492[] = {
     60	{   512000, P_PLL4, 4, 1, 240 },
     61	{   768000, P_PLL4, 4, 1, 160 },
     62	{  1024000, P_PLL4, 4, 1, 120 },
     63	{  1536000, P_PLL4, 4, 1,  80 },
     64	{  2048000, P_PLL4, 4, 1,  60 },
     65	{  3072000, P_PLL4, 4, 1,  40 },
     66	{  4096000, P_PLL4, 4, 1,  30 },
     67	{  6144000, P_PLL4, 4, 1,  20 },
     68	{  8192000, P_PLL4, 4, 1,  15 },
     69	{ 12288000, P_PLL4, 4, 1,  10 },
     70	{ 24576000, P_PLL4, 4, 1,   5 },
     71	{ 27000000, P_CXO,  1, 0,   0 },
     72	{ }
     73};
     74
     75static struct freq_tbl clk_tbl_aif_osr_393[] = {
     76	{   512000, P_PLL4, 4, 1, 192 },
     77	{   768000, P_PLL4, 4, 1, 128 },
     78	{  1024000, P_PLL4, 4, 1,  96 },
     79	{  1536000, P_PLL4, 4, 1,  64 },
     80	{  2048000, P_PLL4, 4, 1,  48 },
     81	{  3072000, P_PLL4, 4, 1,  32 },
     82	{  4096000, P_PLL4, 4, 1,  24 },
     83	{  6144000, P_PLL4, 4, 1,  16 },
     84	{  8192000, P_PLL4, 4, 1,  12 },
     85	{ 12288000, P_PLL4, 4, 1,   8 },
     86	{ 24576000, P_PLL4, 4, 1,   4 },
     87	{ 27000000, P_CXO,  1, 0,   0 },
     88	{ }
     89};
     90
     91static struct clk_rcg mi2s_osr_src = {
     92	.ns_reg = 0x48,
     93	.md_reg = 0x4c,
     94	.mn = {
     95		.mnctr_en_bit = 8,
     96		.mnctr_reset_bit = 7,
     97		.mnctr_mode_shift = 5,
     98		.n_val_shift = 24,
     99		.m_val_shift = 8,
    100		.width = 8,
    101	},
    102	.p = {
    103		.pre_div_shift = 3,
    104		.pre_div_width = 2,
    105	},
    106	.s = {
    107		.src_sel_shift = 0,
    108		.parent_map = lcc_cxo_pll4_map,
    109	},
    110	.freq_tbl = clk_tbl_aif_osr_393,
    111	.clkr = {
    112		.enable_reg = 0x48,
    113		.enable_mask = BIT(9),
    114		.hw.init = &(struct clk_init_data){
    115			.name = "mi2s_osr_src",
    116			.parent_names = lcc_cxo_pll4,
    117			.num_parents = 2,
    118			.ops = &clk_rcg_ops,
    119			.flags = CLK_SET_RATE_GATE,
    120		},
    121	},
    122};
    123
    124static const char * const lcc_mi2s_parents[] = {
    125	"mi2s_osr_src",
    126};
    127
    128static struct clk_branch mi2s_osr_clk = {
    129	.halt_reg = 0x50,
    130	.halt_bit = 1,
    131	.halt_check = BRANCH_HALT_ENABLE,
    132	.clkr = {
    133		.enable_reg = 0x48,
    134		.enable_mask = BIT(17),
    135		.hw.init = &(struct clk_init_data){
    136			.name = "mi2s_osr_clk",
    137			.parent_names = lcc_mi2s_parents,
    138			.num_parents = 1,
    139			.ops = &clk_branch_ops,
    140			.flags = CLK_SET_RATE_PARENT,
    141		},
    142	},
    143};
    144
    145static struct clk_regmap_div mi2s_div_clk = {
    146	.reg = 0x48,
    147	.shift = 10,
    148	.width = 4,
    149	.clkr = {
    150		.enable_reg = 0x48,
    151		.enable_mask = BIT(15),
    152		.hw.init = &(struct clk_init_data){
    153			.name = "mi2s_div_clk",
    154			.parent_names = lcc_mi2s_parents,
    155			.num_parents = 1,
    156			.ops = &clk_regmap_div_ops,
    157		},
    158	},
    159};
    160
    161static struct clk_branch mi2s_bit_div_clk = {
    162	.halt_reg = 0x50,
    163	.halt_bit = 0,
    164	.halt_check = BRANCH_HALT_ENABLE,
    165	.clkr = {
    166		.enable_reg = 0x48,
    167		.enable_mask = BIT(15),
    168		.hw.init = &(struct clk_init_data){
    169			.name = "mi2s_bit_div_clk",
    170			.parent_names = (const char *[]){ "mi2s_div_clk" },
    171			.num_parents = 1,
    172			.ops = &clk_branch_ops,
    173			.flags = CLK_SET_RATE_PARENT,
    174		},
    175	},
    176};
    177
    178static struct clk_regmap_mux mi2s_bit_clk = {
    179	.reg = 0x48,
    180	.shift = 14,
    181	.width = 1,
    182	.clkr = {
    183		.hw.init = &(struct clk_init_data){
    184			.name = "mi2s_bit_clk",
    185			.parent_names = (const char *[]){
    186				"mi2s_bit_div_clk",
    187				"mi2s_codec_clk",
    188			},
    189			.num_parents = 2,
    190			.ops = &clk_regmap_mux_closest_ops,
    191			.flags = CLK_SET_RATE_PARENT,
    192		},
    193	},
    194};
    195
    196#define CLK_AIF_OSR_DIV(prefix, _ns, _md, hr)			\
    197static struct clk_rcg prefix##_osr_src = {			\
    198	.ns_reg = _ns,						\
    199	.md_reg = _md,						\
    200	.mn = {							\
    201		.mnctr_en_bit = 8,				\
    202		.mnctr_reset_bit = 7,				\
    203		.mnctr_mode_shift = 5,				\
    204		.n_val_shift = 24,				\
    205		.m_val_shift = 8,				\
    206		.width = 8,					\
    207	},							\
    208	.p = {							\
    209		.pre_div_shift = 3,				\
    210		.pre_div_width = 2,				\
    211	},							\
    212	.s = {							\
    213		.src_sel_shift = 0,				\
    214		.parent_map = lcc_cxo_pll4_map,			\
    215	},							\
    216	.freq_tbl = clk_tbl_aif_osr_393,			\
    217	.clkr = {						\
    218		.enable_reg = _ns,				\
    219		.enable_mask = BIT(9),				\
    220		.hw.init = &(struct clk_init_data){		\
    221			.name = #prefix "_osr_src",		\
    222			.parent_names = lcc_cxo_pll4,		\
    223			.num_parents = 2,			\
    224			.ops = &clk_rcg_ops,			\
    225			.flags = CLK_SET_RATE_GATE,		\
    226		},						\
    227	},							\
    228};								\
    229								\
    230static const char * const lcc_##prefix##_parents[] = {		\
    231	#prefix "_osr_src",					\
    232};								\
    233								\
    234static struct clk_branch prefix##_osr_clk = {			\
    235	.halt_reg = hr,						\
    236	.halt_bit = 1,						\
    237	.halt_check = BRANCH_HALT_ENABLE,			\
    238	.clkr = {						\
    239		.enable_reg = _ns,				\
    240		.enable_mask = BIT(21),				\
    241		.hw.init = &(struct clk_init_data){		\
    242			.name = #prefix "_osr_clk",		\
    243			.parent_names = lcc_##prefix##_parents,	\
    244			.num_parents = 1,			\
    245			.ops = &clk_branch_ops,			\
    246			.flags = CLK_SET_RATE_PARENT,		\
    247		},						\
    248	},							\
    249};								\
    250								\
    251static struct clk_regmap_div prefix##_div_clk = {		\
    252	.reg = _ns,						\
    253	.shift = 10,						\
    254	.width = 8,						\
    255	.clkr = {						\
    256		.hw.init = &(struct clk_init_data){		\
    257			.name = #prefix "_div_clk",		\
    258			.parent_names = lcc_##prefix##_parents,	\
    259			.num_parents = 1,			\
    260			.ops = &clk_regmap_div_ops,		\
    261		},						\
    262	},							\
    263};								\
    264								\
    265static struct clk_branch prefix##_bit_div_clk = {		\
    266	.halt_reg = hr,						\
    267	.halt_bit = 0,						\
    268	.halt_check = BRANCH_HALT_ENABLE,			\
    269	.clkr = {						\
    270		.enable_reg = _ns,				\
    271		.enable_mask = BIT(19),				\
    272		.hw.init = &(struct clk_init_data){		\
    273			.name = #prefix "_bit_div_clk",		\
    274			.parent_names = (const char *[]){	\
    275				#prefix "_div_clk"		\
    276			},					\
    277			.num_parents = 1,			\
    278			.ops = &clk_branch_ops,			\
    279			.flags = CLK_SET_RATE_PARENT,		\
    280		},						\
    281	},							\
    282};								\
    283								\
    284static struct clk_regmap_mux prefix##_bit_clk = {		\
    285	.reg = _ns,						\
    286	.shift = 18,						\
    287	.width = 1,						\
    288	.clkr = {						\
    289		.hw.init = &(struct clk_init_data){		\
    290			.name = #prefix "_bit_clk",		\
    291			.parent_names = (const char *[]){	\
    292				#prefix "_bit_div_clk",		\
    293				#prefix "_codec_clk",		\
    294			},					\
    295			.num_parents = 2,			\
    296			.ops = &clk_regmap_mux_closest_ops,	\
    297			.flags = CLK_SET_RATE_PARENT,		\
    298		},						\
    299	},							\
    300}
    301
    302CLK_AIF_OSR_DIV(codec_i2s_mic, 0x60, 0x64, 0x68);
    303CLK_AIF_OSR_DIV(spare_i2s_mic, 0x78, 0x7c, 0x80);
    304CLK_AIF_OSR_DIV(codec_i2s_spkr, 0x6c, 0x70, 0x74);
    305CLK_AIF_OSR_DIV(spare_i2s_spkr, 0x84, 0x88, 0x8c);
    306
    307static struct freq_tbl clk_tbl_pcm_492[] = {
    308	{   256000, P_PLL4, 4, 1, 480 },
    309	{   512000, P_PLL4, 4, 1, 240 },
    310	{   768000, P_PLL4, 4, 1, 160 },
    311	{  1024000, P_PLL4, 4, 1, 120 },
    312	{  1536000, P_PLL4, 4, 1,  80 },
    313	{  2048000, P_PLL4, 4, 1,  60 },
    314	{  3072000, P_PLL4, 4, 1,  40 },
    315	{  4096000, P_PLL4, 4, 1,  30 },
    316	{  6144000, P_PLL4, 4, 1,  20 },
    317	{  8192000, P_PLL4, 4, 1,  15 },
    318	{ 12288000, P_PLL4, 4, 1,  10 },
    319	{ 24576000, P_PLL4, 4, 1,   5 },
    320	{ 27000000, P_CXO,  1, 0,   0 },
    321	{ }
    322};
    323
    324static struct freq_tbl clk_tbl_pcm_393[] = {
    325	{   256000, P_PLL4, 4, 1, 384 },
    326	{   512000, P_PLL4, 4, 1, 192 },
    327	{   768000, P_PLL4, 4, 1, 128 },
    328	{  1024000, P_PLL4, 4, 1,  96 },
    329	{  1536000, P_PLL4, 4, 1,  64 },
    330	{  2048000, P_PLL4, 4, 1,  48 },
    331	{  3072000, P_PLL4, 4, 1,  32 },
    332	{  4096000, P_PLL4, 4, 1,  24 },
    333	{  6144000, P_PLL4, 4, 1,  16 },
    334	{  8192000, P_PLL4, 4, 1,  12 },
    335	{ 12288000, P_PLL4, 4, 1,   8 },
    336	{ 24576000, P_PLL4, 4, 1,   4 },
    337	{ 27000000, P_CXO,  1, 0,   0 },
    338	{ }
    339};
    340
    341static struct clk_rcg pcm_src = {
    342	.ns_reg = 0x54,
    343	.md_reg = 0x58,
    344	.mn = {
    345		.mnctr_en_bit = 8,
    346		.mnctr_reset_bit = 7,
    347		.mnctr_mode_shift = 5,
    348		.n_val_shift = 16,
    349		.m_val_shift = 16,
    350		.width = 16,
    351	},
    352	.p = {
    353		.pre_div_shift = 3,
    354		.pre_div_width = 2,
    355	},
    356	.s = {
    357		.src_sel_shift = 0,
    358		.parent_map = lcc_cxo_pll4_map,
    359	},
    360	.freq_tbl = clk_tbl_pcm_393,
    361	.clkr = {
    362		.enable_reg = 0x54,
    363		.enable_mask = BIT(9),
    364		.hw.init = &(struct clk_init_data){
    365			.name = "pcm_src",
    366			.parent_names = lcc_cxo_pll4,
    367			.num_parents = 2,
    368			.ops = &clk_rcg_ops,
    369			.flags = CLK_SET_RATE_GATE,
    370		},
    371	},
    372};
    373
    374static struct clk_branch pcm_clk_out = {
    375	.halt_reg = 0x5c,
    376	.halt_bit = 0,
    377	.halt_check = BRANCH_HALT_ENABLE,
    378	.clkr = {
    379		.enable_reg = 0x54,
    380		.enable_mask = BIT(11),
    381		.hw.init = &(struct clk_init_data){
    382			.name = "pcm_clk_out",
    383			.parent_names = (const char *[]){ "pcm_src" },
    384			.num_parents = 1,
    385			.ops = &clk_branch_ops,
    386			.flags = CLK_SET_RATE_PARENT,
    387		},
    388	},
    389};
    390
    391static struct clk_regmap_mux pcm_clk = {
    392	.reg = 0x54,
    393	.shift = 10,
    394	.width = 1,
    395	.clkr = {
    396		.hw.init = &(struct clk_init_data){
    397			.name = "pcm_clk",
    398			.parent_names = (const char *[]){
    399				"pcm_clk_out",
    400				"pcm_codec_clk",
    401			},
    402			.num_parents = 2,
    403			.ops = &clk_regmap_mux_closest_ops,
    404			.flags = CLK_SET_RATE_PARENT,
    405		},
    406	},
    407};
    408
    409static struct clk_rcg slimbus_src = {
    410	.ns_reg = 0xcc,
    411	.md_reg = 0xd0,
    412	.mn = {
    413		.mnctr_en_bit = 8,
    414		.mnctr_reset_bit = 7,
    415		.mnctr_mode_shift = 5,
    416		.n_val_shift = 24,
    417		.m_val_shift = 8,
    418		.width = 8,
    419	},
    420	.p = {
    421		.pre_div_shift = 3,
    422		.pre_div_width = 2,
    423	},
    424	.s = {
    425		.src_sel_shift = 0,
    426		.parent_map = lcc_cxo_pll4_map,
    427	},
    428	.freq_tbl = clk_tbl_aif_osr_393,
    429	.clkr = {
    430		.enable_reg = 0xcc,
    431		.enable_mask = BIT(9),
    432		.hw.init = &(struct clk_init_data){
    433			.name = "slimbus_src",
    434			.parent_names = lcc_cxo_pll4,
    435			.num_parents = 2,
    436			.ops = &clk_rcg_ops,
    437			.flags = CLK_SET_RATE_GATE,
    438		},
    439	},
    440};
    441
    442static const char * const lcc_slimbus_parents[] = {
    443	"slimbus_src",
    444};
    445
    446static struct clk_branch audio_slimbus_clk = {
    447	.halt_reg = 0xd4,
    448	.halt_bit = 0,
    449	.halt_check = BRANCH_HALT_ENABLE,
    450	.clkr = {
    451		.enable_reg = 0xcc,
    452		.enable_mask = BIT(10),
    453		.hw.init = &(struct clk_init_data){
    454			.name = "audio_slimbus_clk",
    455			.parent_names = lcc_slimbus_parents,
    456			.num_parents = 1,
    457			.ops = &clk_branch_ops,
    458			.flags = CLK_SET_RATE_PARENT,
    459		},
    460	},
    461};
    462
    463static struct clk_branch sps_slimbus_clk = {
    464	.halt_reg = 0xd4,
    465	.halt_bit = 1,
    466	.halt_check = BRANCH_HALT_ENABLE,
    467	.clkr = {
    468		.enable_reg = 0xcc,
    469		.enable_mask = BIT(12),
    470		.hw.init = &(struct clk_init_data){
    471			.name = "sps_slimbus_clk",
    472			.parent_names = lcc_slimbus_parents,
    473			.num_parents = 1,
    474			.ops = &clk_branch_ops,
    475			.flags = CLK_SET_RATE_PARENT,
    476		},
    477	},
    478};
    479
    480static struct clk_regmap *lcc_mdm9615_clks[] = {
    481	[PLL4] = &pll4.clkr,
    482	[MI2S_OSR_SRC] = &mi2s_osr_src.clkr,
    483	[MI2S_OSR_CLK] = &mi2s_osr_clk.clkr,
    484	[MI2S_DIV_CLK] = &mi2s_div_clk.clkr,
    485	[MI2S_BIT_DIV_CLK] = &mi2s_bit_div_clk.clkr,
    486	[MI2S_BIT_CLK] = &mi2s_bit_clk.clkr,
    487	[PCM_SRC] = &pcm_src.clkr,
    488	[PCM_CLK_OUT] = &pcm_clk_out.clkr,
    489	[PCM_CLK] = &pcm_clk.clkr,
    490	[SLIMBUS_SRC] = &slimbus_src.clkr,
    491	[AUDIO_SLIMBUS_CLK] = &audio_slimbus_clk.clkr,
    492	[SPS_SLIMBUS_CLK] = &sps_slimbus_clk.clkr,
    493	[CODEC_I2S_MIC_OSR_SRC] = &codec_i2s_mic_osr_src.clkr,
    494	[CODEC_I2S_MIC_OSR_CLK] = &codec_i2s_mic_osr_clk.clkr,
    495	[CODEC_I2S_MIC_DIV_CLK] = &codec_i2s_mic_div_clk.clkr,
    496	[CODEC_I2S_MIC_BIT_DIV_CLK] = &codec_i2s_mic_bit_div_clk.clkr,
    497	[CODEC_I2S_MIC_BIT_CLK] = &codec_i2s_mic_bit_clk.clkr,
    498	[SPARE_I2S_MIC_OSR_SRC] = &spare_i2s_mic_osr_src.clkr,
    499	[SPARE_I2S_MIC_OSR_CLK] = &spare_i2s_mic_osr_clk.clkr,
    500	[SPARE_I2S_MIC_DIV_CLK] = &spare_i2s_mic_div_clk.clkr,
    501	[SPARE_I2S_MIC_BIT_DIV_CLK] = &spare_i2s_mic_bit_div_clk.clkr,
    502	[SPARE_I2S_MIC_BIT_CLK] = &spare_i2s_mic_bit_clk.clkr,
    503	[CODEC_I2S_SPKR_OSR_SRC] = &codec_i2s_spkr_osr_src.clkr,
    504	[CODEC_I2S_SPKR_OSR_CLK] = &codec_i2s_spkr_osr_clk.clkr,
    505	[CODEC_I2S_SPKR_DIV_CLK] = &codec_i2s_spkr_div_clk.clkr,
    506	[CODEC_I2S_SPKR_BIT_DIV_CLK] = &codec_i2s_spkr_bit_div_clk.clkr,
    507	[CODEC_I2S_SPKR_BIT_CLK] = &codec_i2s_spkr_bit_clk.clkr,
    508	[SPARE_I2S_SPKR_OSR_SRC] = &spare_i2s_spkr_osr_src.clkr,
    509	[SPARE_I2S_SPKR_OSR_CLK] = &spare_i2s_spkr_osr_clk.clkr,
    510	[SPARE_I2S_SPKR_DIV_CLK] = &spare_i2s_spkr_div_clk.clkr,
    511	[SPARE_I2S_SPKR_BIT_DIV_CLK] = &spare_i2s_spkr_bit_div_clk.clkr,
    512	[SPARE_I2S_SPKR_BIT_CLK] = &spare_i2s_spkr_bit_clk.clkr,
    513};
    514
    515static const struct regmap_config lcc_mdm9615_regmap_config = {
    516	.reg_bits	= 32,
    517	.reg_stride	= 4,
    518	.val_bits	= 32,
    519	.max_register	= 0xfc,
    520	.fast_io	= true,
    521};
    522
    523static const struct qcom_cc_desc lcc_mdm9615_desc = {
    524	.config = &lcc_mdm9615_regmap_config,
    525	.clks = lcc_mdm9615_clks,
    526	.num_clks = ARRAY_SIZE(lcc_mdm9615_clks),
    527};
    528
    529static const struct of_device_id lcc_mdm9615_match_table[] = {
    530	{ .compatible = "qcom,lcc-mdm9615" },
    531	{ }
    532};
    533MODULE_DEVICE_TABLE(of, lcc_mdm9615_match_table);
    534
    535static int lcc_mdm9615_probe(struct platform_device *pdev)
    536{
    537	u32 val;
    538	struct regmap *regmap;
    539
    540	regmap = qcom_cc_map(pdev, &lcc_mdm9615_desc);
    541	if (IS_ERR(regmap))
    542		return PTR_ERR(regmap);
    543
    544	/* Use the correct frequency plan depending on speed of PLL4 */
    545	regmap_read(regmap, 0x4, &val);
    546	if (val == 0x12) {
    547		slimbus_src.freq_tbl = clk_tbl_aif_osr_492;
    548		mi2s_osr_src.freq_tbl = clk_tbl_aif_osr_492;
    549		codec_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492;
    550		spare_i2s_mic_osr_src.freq_tbl = clk_tbl_aif_osr_492;
    551		codec_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492;
    552		spare_i2s_spkr_osr_src.freq_tbl = clk_tbl_aif_osr_492;
    553		pcm_src.freq_tbl = clk_tbl_pcm_492;
    554	}
    555	/* Enable PLL4 source on the LPASS Primary PLL Mux */
    556	regmap_write(regmap, 0xc4, 0x1);
    557
    558	return qcom_cc_really_probe(pdev, &lcc_mdm9615_desc, regmap);
    559}
    560
    561static struct platform_driver lcc_mdm9615_driver = {
    562	.probe		= lcc_mdm9615_probe,
    563	.driver		= {
    564		.name	= "lcc-mdm9615",
    565		.of_match_table = lcc_mdm9615_match_table,
    566	},
    567};
    568module_platform_driver(lcc_mdm9615_driver);
    569
    570MODULE_DESCRIPTION("QCOM LCC MDM9615 Driver");
    571MODULE_LICENSE("GPL v2");
    572MODULE_ALIAS("platform:lcc-mdm9615");