Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.2.
  1/*
  2 * tegra_asoc_utils.c - Harmony machine ASoC driver
  3 *
  4 * Author: Stephen Warren <swarren@nvidia.com>
  5 * Copyright (C) 2010 - NVIDIA, Inc.
  6 *
  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.
 10 *
 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.
 15 *
 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
 19 * 02110-1301 USA
 20 *
 21 */
 22
 23#include <linux/clk.h>
 24#include <linux/device.h>
 25#include <linux/err.h>
 26#include <linux/kernel.h>
 27
 28#include "tegra_asoc_utils.h"
 29
 30int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
 31			      int mclk)
 32{
 33	int new_baseclock;
 34	bool clk_change;
 35	int err;
 36
 37	switch (srate) {
 38	case 11025:
 39	case 22050:
 40	case 44100:
 41	case 88200:
 42		new_baseclock = 56448000;
 43		break;
 44	case 8000:
 45	case 16000:
 46	case 32000:
 47	case 48000:
 48	case 64000:
 49	case 96000:
 50		new_baseclock = 73728000;
 51		break;
 52	default:
 53		return -EINVAL;
 54	}
 55
 56	clk_change = ((new_baseclock != data->set_baseclock) ||
 57			(mclk != data->set_mclk));
 58	if (!clk_change)
 59		return 0;
 60
 61	data->set_baseclock = 0;
 62	data->set_mclk = 0;
 63
 64	clk_disable(data->clk_cdev1);
 65	clk_disable(data->clk_pll_a_out0);
 66	clk_disable(data->clk_pll_a);
 67
 68	err = clk_set_rate(data->clk_pll_a, new_baseclock);
 69	if (err) {
 70		dev_err(data->dev, "Can't set pll_a rate: %d\n", err);
 71		return err;
 72	}
 73
 74	err = clk_set_rate(data->clk_pll_a_out0, mclk);
 75	if (err) {
 76		dev_err(data->dev, "Can't set pll_a_out0 rate: %d\n", err);
 77		return err;
 78	}
 79
 80	/* Don't set cdev1 rate; its locked to pll_a_out0 */
 81
 82	err = clk_enable(data->clk_pll_a);
 83	if (err) {
 84		dev_err(data->dev, "Can't enable pll_a: %d\n", err);
 85		return err;
 86	}
 87
 88	err = clk_enable(data->clk_pll_a_out0);
 89	if (err) {
 90		dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err);
 91		return err;
 92	}
 93
 94	err = clk_enable(data->clk_cdev1);
 95	if (err) {
 96		dev_err(data->dev, "Can't enable cdev1: %d\n", err);
 97		return err;
 98	}
 99
100	data->set_baseclock = new_baseclock;
101	data->set_mclk = mclk;
102
103	return 0;
104}
105EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_rate);
106
107int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
108			  struct device *dev)
109{
110	int ret;
111
112	data->dev = dev;
113
114	data->clk_pll_a = clk_get_sys(NULL, "pll_a");
115	if (IS_ERR(data->clk_pll_a)) {
116		dev_err(data->dev, "Can't retrieve clk pll_a\n");
117		ret = PTR_ERR(data->clk_pll_a);
118		goto err;
119	}
120
121	data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0");
122	if (IS_ERR(data->clk_pll_a_out0)) {
123		dev_err(data->dev, "Can't retrieve clk pll_a_out0\n");
124		ret = PTR_ERR(data->clk_pll_a_out0);
125		goto err_put_pll_a;
126	}
127
128	data->clk_cdev1 = clk_get_sys(NULL, "cdev1");
129	if (IS_ERR(data->clk_cdev1)) {
130		dev_err(data->dev, "Can't retrieve clk cdev1\n");
131		ret = PTR_ERR(data->clk_cdev1);
132		goto err_put_pll_a_out0;
133	}
134
135	return 0;
136
137err_put_pll_a_out0:
138	clk_put(data->clk_pll_a_out0);
139err_put_pll_a:
140	clk_put(data->clk_pll_a);
141err:
142	return ret;
143}
144EXPORT_SYMBOL_GPL(tegra_asoc_utils_init);
145
146void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data)
147{
148	clk_put(data->clk_cdev1);
149	clk_put(data->clk_pll_a_out0);
150	clk_put(data->clk_pll_a);
151}
152EXPORT_SYMBOL_GPL(tegra_asoc_utils_fini);
153
154MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
155MODULE_DESCRIPTION("Tegra ASoC utility code");
156MODULE_LICENSE("GPL");