Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  1/*
  2 * Copyright 2015 Toradex AG
  3 *
  4 * Stefan Agner <stefan@agner.ch>
  5 *
  6 * Freescale TCON device driver
  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 as published by
 10 * the Free Software Foundation; either version 2 of the License, or
 11 * (at your option) any later version.
 12 */
 13
 14#include <linux/clk.h>
 15#include <linux/io.h>
 16#include <linux/mm.h>
 17#include <linux/of_address.h>
 18#include <linux/platform_device.h>
 19#include <linux/regmap.h>
 20
 21#include "fsl_tcon.h"
 22
 23void fsl_tcon_bypass_disable(struct fsl_tcon *tcon)
 24{
 25	regmap_update_bits(tcon->regs, FSL_TCON_CTRL1,
 26			   FSL_TCON_CTRL1_TCON_BYPASS, 0);
 27}
 28
 29void fsl_tcon_bypass_enable(struct fsl_tcon *tcon)
 30{
 31	regmap_update_bits(tcon->regs, FSL_TCON_CTRL1,
 32			   FSL_TCON_CTRL1_TCON_BYPASS,
 33			   FSL_TCON_CTRL1_TCON_BYPASS);
 34}
 35
 36static struct regmap_config fsl_tcon_regmap_config = {
 37	.reg_bits = 32,
 38	.reg_stride = 4,
 39	.val_bits = 32,
 40
 41	.name = "tcon",
 42};
 43
 44static int fsl_tcon_init_regmap(struct device *dev,
 45				struct fsl_tcon *tcon,
 46				struct device_node *np)
 47{
 48	struct resource res;
 49	void __iomem *regs;
 50
 51	if (of_address_to_resource(np, 0, &res))
 52		return -EINVAL;
 53
 54	regs = devm_ioremap_resource(dev, &res);
 55	if (IS_ERR(regs))
 56		return PTR_ERR(regs);
 57
 58	tcon->regs = devm_regmap_init_mmio(dev, regs,
 59					   &fsl_tcon_regmap_config);
 60	return PTR_ERR_OR_ZERO(tcon->regs);
 61}
 62
 63struct fsl_tcon *fsl_tcon_init(struct device *dev)
 64{
 65	struct fsl_tcon *tcon;
 66	struct device_node *np;
 67	int ret;
 68
 69	/* TCON node is not mandatory, some devices do not provide TCON */
 70	np = of_parse_phandle(dev->of_node, "fsl,tcon", 0);
 71	if (!np)
 72		return NULL;
 73
 74	tcon = devm_kzalloc(dev, sizeof(*tcon), GFP_KERNEL);
 75	if (!tcon) {
 76		ret = -ENOMEM;
 77		goto err_node_put;
 78	}
 79
 80	ret = fsl_tcon_init_regmap(dev, tcon, np);
 81	if (ret) {
 82		dev_err(dev, "Couldn't create the TCON regmap\n");
 83		goto err_node_put;
 84	}
 85
 86	tcon->ipg_clk = of_clk_get_by_name(np, "ipg");
 87	if (IS_ERR(tcon->ipg_clk)) {
 88		dev_err(dev, "Couldn't get the TCON bus clock\n");
 89		goto err_node_put;
 90	}
 91
 92	of_node_put(np);
 93	clk_prepare_enable(tcon->ipg_clk);
 94
 95	dev_info(dev, "Using TCON in bypass mode\n");
 96
 97	return tcon;
 98
 99err_node_put:
100	of_node_put(np);
101	return NULL;
102}
103
104void fsl_tcon_free(struct fsl_tcon *tcon)
105{
106	clk_disable_unprepare(tcon->ipg_clk);
107	clk_put(tcon->ipg_clk);
108}
109