Linux Audio

Check our new training course

Linux kernel drivers training

Mar 31-Apr 9, 2025, special US time zones
Register
Loading...
Note: File does not exist in v3.1.
  1/*
  2 * Copyright (C) 2013 Red Hat
  3 * Author: Rob Clark <robdclark@gmail.com>
  4 *
  5 * This program is free software; you can redistribute it and/or modify it
  6 * under the terms of the GNU General Public License version 2 as published by
  7 * the Free Software Foundation.
  8 *
  9 * This program is distributed in the hope that it will be useful, but WITHOUT
 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 12 * more details.
 13 *
 14 * You should have received a copy of the GNU General Public License along with
 15 * this program.  If not, see <http://www.gnu.org/licenses/>.
 16 */
 17
 18#include "hdmi.h"
 19
 20struct hdmi_phy_8960 {
 21	struct hdmi_phy base;
 22	struct hdmi *hdmi;
 23};
 24#define to_hdmi_phy_8960(x) container_of(x, struct hdmi_phy_8960, base)
 25
 26static void hdmi_phy_8960_destroy(struct hdmi_phy *phy)
 27{
 28	struct hdmi_phy_8960 *phy_8960 = to_hdmi_phy_8960(phy);
 29	kfree(phy_8960);
 30}
 31
 32static void hdmi_phy_8960_reset(struct hdmi_phy *phy)
 33{
 34	struct hdmi_phy_8960 *phy_8960 = to_hdmi_phy_8960(phy);
 35	struct hdmi *hdmi = phy_8960->hdmi;
 36	unsigned int val;
 37
 38	val = hdmi_read(hdmi, REG_HDMI_PHY_CTRL);
 39
 40	if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
 41		/* pull low */
 42		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
 43				val & ~HDMI_PHY_CTRL_SW_RESET);
 44	} else {
 45		/* pull high */
 46		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
 47				val | HDMI_PHY_CTRL_SW_RESET);
 48	}
 49
 50	if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
 51		/* pull low */
 52		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
 53				val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
 54	} else {
 55		/* pull high */
 56		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
 57				val | HDMI_PHY_CTRL_SW_RESET_PLL);
 58	}
 59
 60	msleep(100);
 61
 62	if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
 63		/* pull high */
 64		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
 65				val | HDMI_PHY_CTRL_SW_RESET);
 66	} else {
 67		/* pull low */
 68		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
 69				val & ~HDMI_PHY_CTRL_SW_RESET);
 70	}
 71
 72	if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
 73		/* pull high */
 74		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
 75				val | HDMI_PHY_CTRL_SW_RESET_PLL);
 76	} else {
 77		/* pull low */
 78		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
 79				val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
 80	}
 81}
 82
 83static void hdmi_phy_8960_powerup(struct hdmi_phy *phy,
 84		unsigned long int pixclock)
 85{
 86	struct hdmi_phy_8960 *phy_8960 = to_hdmi_phy_8960(phy);
 87	struct hdmi *hdmi = phy_8960->hdmi;
 88
 89	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG0, 0x1b);
 90	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG1, 0xf2);
 91	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG4, 0x00);
 92	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG5, 0x00);
 93	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG6, 0x00);
 94	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG7, 0x00);
 95	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG8, 0x00);
 96	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG9, 0x00);
 97	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG10, 0x00);
 98	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG11, 0x00);
 99	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG3, 0x20);
100}
101
102static void hdmi_phy_8960_powerdown(struct hdmi_phy *phy)
103{
104	struct hdmi_phy_8960 *phy_8960 = to_hdmi_phy_8960(phy);
105	struct hdmi *hdmi = phy_8960->hdmi;
106
107	hdmi_write(hdmi, REG_HDMI_8960_PHY_REG2, 0x7f);
108}
109
110static const struct hdmi_phy_funcs hdmi_phy_8960_funcs = {
111		.destroy = hdmi_phy_8960_destroy,
112		.reset = hdmi_phy_8960_reset,
113		.powerup = hdmi_phy_8960_powerup,
114		.powerdown = hdmi_phy_8960_powerdown,
115};
116
117struct hdmi_phy *hdmi_phy_8960_init(struct hdmi *hdmi)
118{
119	struct hdmi_phy_8960 *phy_8960;
120	struct hdmi_phy *phy = NULL;
121	int ret;
122
123	phy_8960 = kzalloc(sizeof(*phy_8960), GFP_KERNEL);
124	if (!phy_8960) {
125		ret = -ENOMEM;
126		goto fail;
127	}
128
129	phy = &phy_8960->base;
130
131	phy->funcs = &hdmi_phy_8960_funcs;
132
133	phy_8960->hdmi = hdmi;
134
135	return phy;
136
137fail:
138	if (phy)
139		hdmi_phy_8960_destroy(phy);
140	return ERR_PTR(ret);
141}