683 lines
19 KiB
C
683 lines
19 KiB
C
/*
|
|
* drivers/video/tegra/dc/dc_sysfs.c
|
|
*
|
|
* Copyright (c) 2011-2013, NVIDIA CORPORATION, All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <linux/fb.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/kernel.h>
|
|
|
|
#include "dc_reg.h"
|
|
#include "dc_priv.h"
|
|
#include "nvsd.h"
|
|
#include "hdmi.h"
|
|
|
|
static ssize_t mode_show(struct device *device,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(device);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
struct tegra_dc_mode *m;
|
|
ssize_t res;
|
|
|
|
mutex_lock(&dc->lock);
|
|
m = &dc->mode;
|
|
res = snprintf(buf, PAGE_SIZE,
|
|
"pclk: %d\n"
|
|
"h_ref_to_sync: %d\n"
|
|
"v_ref_to_sync: %d\n"
|
|
"h_sync_width: %d\n"
|
|
"v_sync_width: %d\n"
|
|
"h_back_porch: %d\n"
|
|
"v_back_porch: %d\n"
|
|
"h_active: %d\n"
|
|
"v_active: %d\n"
|
|
"h_front_porch: %d\n"
|
|
"v_front_porch: %d\n"
|
|
"stereo_mode: %d\n",
|
|
m->pclk, m->h_ref_to_sync, m->v_ref_to_sync,
|
|
m->h_sync_width, m->v_sync_width,
|
|
m->h_back_porch, m->v_back_porch,
|
|
m->h_active, m->v_active,
|
|
m->h_front_porch, m->v_front_porch,
|
|
m->stereo_mode);
|
|
mutex_unlock(&dc->lock);
|
|
|
|
return res;
|
|
}
|
|
|
|
static DEVICE_ATTR(mode, S_IRUGO, mode_show, NULL);
|
|
|
|
static ssize_t stats_enable_show(struct device *dev,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
bool enabled;
|
|
|
|
if (mutex_lock_killable(&dc->lock))
|
|
return -EINTR;
|
|
enabled = tegra_dc_stats_get(dc);
|
|
mutex_unlock(&dc->lock);
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%d\n", enabled);
|
|
}
|
|
|
|
static ssize_t stats_enable_store(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t count)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
unsigned long val = 0;
|
|
|
|
if (kstrtoul(buf, 10, &val) < 0)
|
|
return -EINVAL;
|
|
|
|
if (mutex_lock_killable(&dc->lock))
|
|
return -EINTR;
|
|
tegra_dc_stats_enable(dc, !!val);
|
|
mutex_unlock(&dc->lock);
|
|
|
|
return count;
|
|
}
|
|
|
|
static DEVICE_ATTR(stats_enable, S_IRUGO|S_IWUSR,
|
|
stats_enable_show, stats_enable_store);
|
|
|
|
static ssize_t enable_show(struct device *device,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(device);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
ssize_t res;
|
|
|
|
mutex_lock(&dc->lock);
|
|
res = snprintf(buf, PAGE_SIZE, "%d\n", dc->enabled);
|
|
mutex_unlock(&dc->lock);
|
|
return res;
|
|
}
|
|
|
|
static ssize_t enable_store(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t count)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
unsigned long val = 0;
|
|
|
|
if (kstrtoul(buf, 10, &val) < 0)
|
|
return -EINVAL;
|
|
|
|
if (val)
|
|
tegra_dc_enable(dc);
|
|
else
|
|
tegra_dc_disable(dc);
|
|
|
|
return count;
|
|
}
|
|
|
|
static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, enable_show, enable_store);
|
|
|
|
static ssize_t crc_checksum_latched_show(struct device *device,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(device);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
|
|
u32 crc;
|
|
|
|
if (!dc->enabled) {
|
|
dev_err(&dc->ndev->dev, "%s: DC not enabled.\n", __func__);
|
|
return -EFAULT;
|
|
}
|
|
|
|
crc = tegra_dc_read_checksum_latched(dc);
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%u\n", crc);
|
|
}
|
|
|
|
static ssize_t crc_checksum_latched_store(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t count)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
unsigned long val = 0;
|
|
|
|
if (!dc->enabled) {
|
|
dev_err(&dc->ndev->dev, "%s: DC not enabled.\n", __func__);
|
|
return -EFAULT;
|
|
}
|
|
|
|
if (kstrtoul(buf, 10, &val) < 0)
|
|
return -EINVAL;
|
|
|
|
if (val == 1) {
|
|
tegra_dc_enable_crc(dc);
|
|
dev_dbg(&dc->ndev->dev, "crc is enabled.\n");
|
|
} else if (val == 0) {
|
|
tegra_dc_disable_crc(dc);
|
|
dev_dbg(&dc->ndev->dev, "crc is disabled.\n");
|
|
} else
|
|
dev_err(&dc->ndev->dev, "Invalid input.\n");
|
|
|
|
return count;
|
|
}
|
|
static DEVICE_ATTR(crc_checksum_latched, S_IRUGO|S_IWUSR,
|
|
crc_checksum_latched_show, crc_checksum_latched_store);
|
|
|
|
#define ORIENTATION_PORTRAIT "portrait"
|
|
#define ORIENTATION_LANDSCAPE "landscape"
|
|
|
|
static ssize_t orientation_3d_show(struct device *dev,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
struct tegra_dc_out *dc_out = dc->out;
|
|
const char *orientation;
|
|
switch (dc_out->stereo->orientation) {
|
|
case TEGRA_DC_STEREO_LANDSCAPE:
|
|
orientation = ORIENTATION_LANDSCAPE;
|
|
break;
|
|
case TEGRA_DC_STEREO_PORTRAIT:
|
|
orientation = ORIENTATION_PORTRAIT;
|
|
break;
|
|
default:
|
|
pr_err("Invalid value is stored for stereo_orientation.\n");
|
|
return -EINVAL;
|
|
}
|
|
return snprintf(buf, PAGE_SIZE, "%s\n", orientation);
|
|
}
|
|
|
|
static ssize_t orientation_3d_store(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t cnt)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
struct tegra_dc_out *dc_out = dc->out;
|
|
struct tegra_stereo_out *stereo = dc_out->stereo;
|
|
int orientation;
|
|
|
|
if (0 == strncmp(buf, ORIENTATION_PORTRAIT,
|
|
min(cnt, ARRAY_SIZE(ORIENTATION_PORTRAIT) - 1))) {
|
|
orientation = TEGRA_DC_STEREO_PORTRAIT;
|
|
} else if (0 == strncmp(buf, ORIENTATION_LANDSCAPE,
|
|
min(cnt, ARRAY_SIZE(ORIENTATION_LANDSCAPE) - 1))) {
|
|
orientation = TEGRA_DC_STEREO_LANDSCAPE;
|
|
} else {
|
|
pr_err("Invalid property value for stereo_orientation.\n");
|
|
return -EINVAL;
|
|
}
|
|
stereo->orientation = orientation;
|
|
stereo->set_orientation(orientation);
|
|
return cnt;
|
|
}
|
|
|
|
static DEVICE_ATTR(stereo_orientation,
|
|
S_IRUGO|S_IWUSR, orientation_3d_show, orientation_3d_store);
|
|
|
|
#define MODE_2D "2d"
|
|
#define MODE_3D "3d"
|
|
|
|
static ssize_t mode_3d_show(struct device *dev,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
struct tegra_dc_out *dc_out = dc->out;
|
|
const char *mode;
|
|
switch (dc_out->stereo->mode_2d_3d) {
|
|
case TEGRA_DC_STEREO_MODE_2D:
|
|
mode = MODE_2D;
|
|
break;
|
|
case TEGRA_DC_STEREO_MODE_3D:
|
|
mode = MODE_3D;
|
|
break;
|
|
default:
|
|
pr_err("Invalid value is stored for stereo_mode.\n");
|
|
return -EINVAL;
|
|
}
|
|
return snprintf(buf, PAGE_SIZE, "%s\n", mode);
|
|
}
|
|
|
|
static ssize_t mode_3d_store(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t cnt)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
struct tegra_dc_out *dc_out = dc->out;
|
|
struct tegra_stereo_out *stereo = dc_out->stereo;
|
|
int mode;
|
|
|
|
if (0 == strncmp(buf, MODE_2D, min(cnt, ARRAY_SIZE(MODE_2D) - 1))) {
|
|
mode = TEGRA_DC_STEREO_MODE_2D;
|
|
} else if (0 == strncmp(buf, MODE_3D,
|
|
min(cnt, ARRAY_SIZE(MODE_3D) - 1))) {
|
|
mode = TEGRA_DC_STEREO_MODE_3D;
|
|
} else {
|
|
pr_err("Invalid property value for stereo_mode.\n");
|
|
return -EINVAL;
|
|
}
|
|
stereo->mode_2d_3d = mode;
|
|
stereo->set_mode(mode);
|
|
return cnt;
|
|
}
|
|
|
|
static DEVICE_ATTR(stereo_mode,
|
|
S_IRUGO|S_IWUSR, mode_3d_show, mode_3d_store);
|
|
|
|
static ssize_t nvdps_show(struct device *device,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
int refresh_rate;
|
|
struct platform_device *ndev = to_platform_device(device);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
|
|
refresh_rate = tegra_fb_get_mode(dc);
|
|
return snprintf(buf, PAGE_SIZE, "%d\n", refresh_rate);
|
|
}
|
|
|
|
|
|
static ssize_t nvdps_store(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t count)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
int refresh_rate;
|
|
int e;
|
|
|
|
e = kstrtoint(buf, 10, &refresh_rate);
|
|
if (e)
|
|
return e;
|
|
e = tegra_fb_set_mode(dc, refresh_rate);
|
|
|
|
return count;
|
|
}
|
|
|
|
static DEVICE_ATTR(nvdps, S_IRUGO|S_IWUSR, nvdps_show, nvdps_store);
|
|
|
|
#ifdef CONFIG_TEGRA_DC_CMU
|
|
static ssize_t cmu_enable_store(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t count)
|
|
{
|
|
int val;
|
|
int e;
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
|
|
e = kstrtoint(buf, 10, &val);
|
|
if (e)
|
|
return e;
|
|
|
|
tegra_dc_cmu_enable(dc, val);
|
|
|
|
return count;
|
|
}
|
|
|
|
static ssize_t cmu_enable_show(struct device *dev,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%d\n", dc->pdata->cmu_enable);
|
|
}
|
|
|
|
static DEVICE_ATTR(cmu_enable,
|
|
S_IRUGO|S_IWUSR, cmu_enable_show, cmu_enable_store);
|
|
#endif
|
|
static ssize_t smart_panel_show(struct device *device,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
return snprintf(buf, PAGE_SIZE, "1\n");
|
|
}
|
|
|
|
static DEVICE_ATTR(smart_panel, S_IRUGO, smart_panel_show, NULL);
|
|
|
|
static ssize_t pclk_show(struct device *device,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(device);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
ssize_t res = 0;
|
|
struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
|
|
|
|
if (hdmi_out->tmds_config && hdmi_out->n_tmds_config) {
|
|
mutex_lock(&dc->lock);
|
|
res = snprintf(buf, PAGE_SIZE, "%d\n",
|
|
hdmi_out->tmds_config[0].pclk);
|
|
mutex_unlock(&dc->lock);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
static ssize_t pclk_store(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t count)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
long val = 0;
|
|
struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
|
|
|
|
if (kstrtol(buf, 10, &val) < 0)
|
|
return -EINVAL;
|
|
|
|
if (hdmi_out->tmds_config && hdmi_out->n_tmds_config)
|
|
hdmi_out->tmds_config[0].pclk = val;
|
|
|
|
return count;
|
|
}
|
|
|
|
static DEVICE_ATTR(pclk, S_IRUGO|S_IWUSR, pclk_show, pclk_store);
|
|
|
|
static ssize_t pll0_show(struct device *device,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(device);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
ssize_t res = 0;
|
|
struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
|
|
|
|
if (hdmi_out->tmds_config && hdmi_out->n_tmds_config) {
|
|
mutex_lock(&dc->lock);
|
|
res = snprintf(buf, PAGE_SIZE, "%d\n",
|
|
hdmi_out->tmds_config[0].pll0);
|
|
mutex_unlock(&dc->lock);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
static ssize_t pll0_store(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t count)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
unsigned long val = 0;
|
|
struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
|
|
|
|
if (kstrtoul(buf, 10, &val) < 0)
|
|
return -EINVAL;
|
|
|
|
if (hdmi_out->tmds_config && hdmi_out->n_tmds_config)
|
|
hdmi_out->tmds_config[0].pll0 = val;
|
|
|
|
return count;
|
|
}
|
|
|
|
static DEVICE_ATTR(pll0, S_IRUGO|S_IWUSR, pll0_show, pll0_store);
|
|
static ssize_t pll1_show(struct device *device,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(device);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
ssize_t res = 0;
|
|
struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
|
|
|
|
if (hdmi_out->tmds_config && hdmi_out->n_tmds_config) {
|
|
mutex_lock(&dc->lock);
|
|
res = snprintf(buf, PAGE_SIZE, "%d\n",
|
|
hdmi_out->tmds_config[0].pll1);
|
|
mutex_unlock(&dc->lock);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
static ssize_t pll1_store(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t count)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
unsigned long val = 0;
|
|
struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
|
|
|
|
if (kstrtoul(buf, 10, &val) < 0)
|
|
return -EINVAL;
|
|
|
|
if (hdmi_out->tmds_config && hdmi_out->n_tmds_config)
|
|
hdmi_out->tmds_config[0].pll1 = val;
|
|
|
|
return count;
|
|
}
|
|
|
|
static DEVICE_ATTR(pll1, S_IRUGO|S_IWUSR, pll1_show, pll1_store);
|
|
static ssize_t pe_current_show(struct device *device,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(device);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
ssize_t res = 0;
|
|
struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
|
|
|
|
if (hdmi_out->tmds_config && hdmi_out->n_tmds_config) {
|
|
mutex_lock(&dc->lock);
|
|
res = snprintf(buf, PAGE_SIZE, "%d\n",
|
|
hdmi_out->tmds_config[0].pe_current);
|
|
mutex_unlock(&dc->lock);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
static ssize_t pe_current_store(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t count)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
unsigned long val = 0;
|
|
struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
|
|
|
|
if (kstrtoul(buf, 10, &val) < 0)
|
|
return -EINVAL;
|
|
|
|
if (hdmi_out->tmds_config && hdmi_out->n_tmds_config)
|
|
hdmi_out->tmds_config[0].pe_current = val;
|
|
|
|
return count;
|
|
}
|
|
|
|
static DEVICE_ATTR(pe_current, S_IRUGO|S_IWUSR, pe_current_show,
|
|
pe_current_store);
|
|
|
|
static ssize_t drive_current_show(struct device *device,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(device);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
ssize_t res = 0;
|
|
struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
|
|
|
|
if (hdmi_out->tmds_config && hdmi_out->n_tmds_config) {
|
|
mutex_lock(&dc->lock);
|
|
res = snprintf(buf, PAGE_SIZE, "%d\n",
|
|
hdmi_out->tmds_config[0].drive_current);
|
|
mutex_unlock(&dc->lock);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
static ssize_t drive_current_store(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t count)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
unsigned long val = 0;
|
|
struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
|
|
|
|
if (kstrtoul(buf, 10, &val) < 0)
|
|
return -EINVAL;
|
|
|
|
if (hdmi_out->tmds_config && hdmi_out->n_tmds_config)
|
|
hdmi_out->tmds_config[0].drive_current = val;
|
|
|
|
return count;
|
|
}
|
|
|
|
static DEVICE_ATTR(drive_current, S_IRUGO|S_IWUSR, drive_current_show,
|
|
drive_current_store);
|
|
|
|
static ssize_t peak_current_show(struct device *device,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(device);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
ssize_t res = 0;
|
|
struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
|
|
|
|
if (hdmi_out->tmds_config && hdmi_out->n_tmds_config) {
|
|
mutex_lock(&dc->lock);
|
|
res = snprintf(buf, PAGE_SIZE, "%d\n",
|
|
hdmi_out->tmds_config[0].peak_current);
|
|
mutex_unlock(&dc->lock);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
static ssize_t peak_current_store(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t count)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
unsigned long val = 0;
|
|
struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
|
|
|
|
if (kstrtoul(buf, 10, &val) < 0)
|
|
return -EINVAL;
|
|
|
|
if (hdmi_out->tmds_config && hdmi_out->n_tmds_config)
|
|
hdmi_out->tmds_config[0].peak_current = val;
|
|
|
|
return count;
|
|
}
|
|
|
|
static DEVICE_ATTR(peak_current, S_IRUGO|S_IWUSR, peak_current_show,
|
|
peak_current_store);
|
|
|
|
static ssize_t dump_config_show(struct device *device,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(device);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
struct tegra_hdmi_out *hdmi_out = dc->out->hdmi_out;
|
|
ssize_t res = 0;
|
|
|
|
if (hdmi_out->tmds_config && hdmi_out->n_tmds_config) {
|
|
mutex_lock(&dc->lock);
|
|
res = snprintf(buf, PAGE_SIZE,
|
|
"pclk: %d\n"
|
|
"pll0: %d\n"
|
|
"pll1: %d\n"
|
|
"pe_current: %d\n"
|
|
"drive_current: %d\n"
|
|
"peak_current: %d\n",
|
|
hdmi_out->tmds_config[0].pclk,
|
|
hdmi_out->tmds_config[0].pll0,
|
|
hdmi_out->tmds_config[0].pll1,
|
|
hdmi_out->tmds_config[0].pe_current,
|
|
hdmi_out->tmds_config[0].drive_current,
|
|
hdmi_out->tmds_config[0].peak_current
|
|
);
|
|
mutex_unlock(&dc->lock);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
static DEVICE_ATTR(dump_config, S_IRUGO, dump_config_show, NULL);
|
|
|
|
static struct attribute *hdmi_config_attrs[] = {
|
|
&dev_attr_pclk.attr,
|
|
&dev_attr_pll0.attr,
|
|
&dev_attr_pll1.attr,
|
|
&dev_attr_pe_current.attr,
|
|
&dev_attr_drive_current.attr,
|
|
&dev_attr_peak_current.attr,
|
|
&dev_attr_dump_config.attr,
|
|
NULL
|
|
};
|
|
|
|
static struct attribute_group hdmi_config_attr_group = {
|
|
.attrs = hdmi_config_attrs,
|
|
.name = "hdmi_config"
|
|
};
|
|
|
|
void tegra_dc_remove_sysfs(struct device *dev)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
struct tegra_dc_sd_settings *sd_settings = dc->out->sd_settings;
|
|
|
|
device_remove_file(dev, &dev_attr_mode);
|
|
device_remove_file(dev, &dev_attr_nvdps);
|
|
device_remove_file(dev, &dev_attr_enable);
|
|
device_remove_file(dev, &dev_attr_stats_enable);
|
|
device_remove_file(dev, &dev_attr_crc_checksum_latched);
|
|
#ifdef CONFIG_TEGRA_DC_CMU
|
|
device_remove_file(dev, &dev_attr_cmu_enable);
|
|
#endif
|
|
|
|
if (dc->out->stereo) {
|
|
device_remove_file(dev, &dev_attr_stereo_orientation);
|
|
device_remove_file(dev, &dev_attr_stereo_mode);
|
|
}
|
|
|
|
if (sd_settings)
|
|
nvsd_remove_sysfs(dev);
|
|
|
|
if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
|
|
device_remove_file(dev, &dev_attr_smart_panel);
|
|
|
|
if (dc->out->type == TEGRA_DC_OUT_HDMI)
|
|
sysfs_remove_group(&dev->kobj, &hdmi_config_attr_group);
|
|
}
|
|
|
|
void tegra_dc_create_sysfs(struct device *dev)
|
|
{
|
|
struct platform_device *ndev = to_platform_device(dev);
|
|
struct tegra_dc *dc = platform_get_drvdata(ndev);
|
|
struct tegra_dc_sd_settings *sd_settings = dc->out->sd_settings;
|
|
int error = 0;
|
|
|
|
error |= device_create_file(dev, &dev_attr_mode);
|
|
error |= device_create_file(dev, &dev_attr_nvdps);
|
|
error |= device_create_file(dev, &dev_attr_enable);
|
|
error |= device_create_file(dev, &dev_attr_stats_enable);
|
|
error |= device_create_file(dev, &dev_attr_crc_checksum_latched);
|
|
#ifdef CONFIG_TEGRA_DC_CMU
|
|
error |= device_create_file(dev, &dev_attr_cmu_enable);
|
|
#endif
|
|
|
|
if (dc->out->stereo) {
|
|
error |= device_create_file(dev, &dev_attr_stereo_orientation);
|
|
error |= device_create_file(dev, &dev_attr_stereo_mode);
|
|
}
|
|
|
|
if (sd_settings)
|
|
error |= nvsd_create_sysfs(dev);
|
|
|
|
if (dc->out->flags & TEGRA_DC_OUT_ONE_SHOT_MODE)
|
|
error |= device_create_file(dev, &dev_attr_smart_panel);
|
|
if (dc->out->type == TEGRA_DC_OUT_HDMI)
|
|
error |= sysfs_create_group(&dev->kobj,
|
|
&hdmi_config_attr_group);
|
|
|
|
if (error)
|
|
dev_err(&ndev->dev, "Failed to create sysfs attributes!\n");
|
|
}
|