2 * tegra20_das.c - Tegra20 DAS driver
4 * Author: Stephen Warren <swarren@nvidia.com>
5 * Copyright (C) 2010 - NVIDIA, Inc.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 #include <linux/device.h>
25 #include <linux/module.h>
26 #include <linux/platform_device.h>
27 #include <linux/regmap.h>
28 #include <linux/slab.h>
29 #include <sound/soc.h>
30 #include "tegra20_das.h"
32 #define DRV_NAME "tegra20-das"
34 static struct tegra20_das
*das
;
36 static inline void tegra20_das_write(u32 reg
, u32 val
)
38 regmap_write(das
->regmap
, reg
, val
);
41 static inline u32
tegra20_das_read(u32 reg
)
44 regmap_read(das
->regmap
, reg
, &val
);
48 int tegra20_das_connect_dap_to_dac(int dap
, int dac
)
56 addr
= TEGRA20_DAS_DAP_CTRL_SEL
+
57 (dap
* TEGRA20_DAS_DAP_CTRL_SEL_STRIDE
);
58 reg
= dac
<< TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P
;
60 tegra20_das_write(addr
, reg
);
64 EXPORT_SYMBOL_GPL(tegra20_das_connect_dap_to_dac
);
66 int tegra20_das_connect_dap_to_dap(int dap
, int otherdap
, int master
,
67 int sdata1rx
, int sdata2rx
)
75 addr
= TEGRA20_DAS_DAP_CTRL_SEL
+
76 (dap
* TEGRA20_DAS_DAP_CTRL_SEL_STRIDE
);
77 reg
= otherdap
<< TEGRA20_DAS_DAP_CTRL_SEL_DAP_CTRL_SEL_P
|
78 !!sdata2rx
<< TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA2_TX_RX_P
|
79 !!sdata1rx
<< TEGRA20_DAS_DAP_CTRL_SEL_DAP_SDATA1_TX_RX_P
|
80 !!master
<< TEGRA20_DAS_DAP_CTRL_SEL_DAP_MS_SEL_P
;
82 tegra20_das_write(addr
, reg
);
86 EXPORT_SYMBOL_GPL(tegra20_das_connect_dap_to_dap
);
88 int tegra20_das_connect_dac_to_dap(int dac
, int dap
)
96 addr
= TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL
+
97 (dac
* TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_STRIDE
);
98 reg
= dap
<< TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_CLK_SEL_P
|
99 dap
<< TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA1_SEL_P
|
100 dap
<< TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL_DAC_SDATA2_SEL_P
;
102 tegra20_das_write(addr
, reg
);
106 EXPORT_SYMBOL_GPL(tegra20_das_connect_dac_to_dap
);
108 #define LAST_REG(name) \
109 (TEGRA20_DAS_##name + \
110 (TEGRA20_DAS_##name##_STRIDE * (TEGRA20_DAS_##name##_COUNT - 1)))
112 static bool tegra20_das_wr_rd_reg(struct device
*dev
, unsigned int reg
)
114 if ((reg
>= TEGRA20_DAS_DAP_CTRL_SEL
) &&
115 (reg
<= LAST_REG(DAP_CTRL_SEL
)))
117 if ((reg
>= TEGRA20_DAS_DAC_INPUT_DATA_CLK_SEL
) &&
118 (reg
<= LAST_REG(DAC_INPUT_DATA_CLK_SEL
)))
124 static const struct regmap_config tegra20_das_regmap_config
= {
128 .max_register
= LAST_REG(DAC_INPUT_DATA_CLK_SEL
),
129 .writeable_reg
= tegra20_das_wr_rd_reg
,
130 .readable_reg
= tegra20_das_wr_rd_reg
,
131 .cache_type
= REGCACHE_RBTREE
,
134 static int tegra20_das_probe(struct platform_device
*pdev
)
136 struct resource
*res
, *region
;
143 das
= devm_kzalloc(&pdev
->dev
, sizeof(struct tegra20_das
), GFP_KERNEL
);
145 dev_err(&pdev
->dev
, "Can't allocate tegra20_das\n");
149 das
->dev
= &pdev
->dev
;
151 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
153 dev_err(&pdev
->dev
, "No memory resource\n");
158 region
= devm_request_mem_region(&pdev
->dev
, res
->start
,
159 resource_size(res
), pdev
->name
);
161 dev_err(&pdev
->dev
, "Memory region already claimed\n");
166 regs
= devm_ioremap(&pdev
->dev
, res
->start
, resource_size(res
));
168 dev_err(&pdev
->dev
, "ioremap failed\n");
173 das
->regmap
= devm_regmap_init_mmio(&pdev
->dev
, regs
,
174 &tegra20_das_regmap_config
);
175 if (IS_ERR(das
->regmap
)) {
176 dev_err(&pdev
->dev
, "regmap init failed\n");
177 ret
= PTR_ERR(das
->regmap
);
181 ret
= tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_1
,
182 TEGRA20_DAS_DAP_SEL_DAC1
);
184 dev_err(&pdev
->dev
, "Can't set up DAS DAP connection\n");
187 ret
= tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAC_ID_1
,
188 TEGRA20_DAS_DAC_SEL_DAP1
);
190 dev_err(&pdev
->dev
, "Can't set up DAS DAC connection\n");
194 ret
= tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_3
,
195 TEGRA20_DAS_DAP_SEL_DAC3
);
197 dev_err(&pdev
->dev
, "Can't set up DAS DAP connection\n");
200 ret
= tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAC_ID_3
,
201 TEGRA20_DAS_DAC_SEL_DAP3
);
203 dev_err(&pdev
->dev
, "Can't set up DAS DAC connection\n");
207 platform_set_drvdata(pdev
, das
);
216 static int tegra20_das_remove(struct platform_device
*pdev
)
226 static const struct of_device_id tegra20_das_of_match
[] = {
227 { .compatible
= "nvidia,tegra20-das", },
231 static struct platform_driver tegra20_das_driver
= {
232 .probe
= tegra20_das_probe
,
233 .remove
= tegra20_das_remove
,
236 .owner
= THIS_MODULE
,
237 .of_match_table
= tegra20_das_of_match
,
240 module_platform_driver(tegra20_das_driver
);
242 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
243 MODULE_DESCRIPTION("Tegra20 DAS driver");
244 MODULE_LICENSE("GPL");
245 MODULE_ALIAS("platform:" DRV_NAME
);
246 MODULE_DEVICE_TABLE(of
, tegra20_das_of_match
);