blob: bf2db5fbe93a98ff24eb0eff768cd4aae9950ac7 [file] [log] [blame]
/*
* drivers/amlogic/media/vin/tvin/hdmirx_ext/hdmirx_ext_attrs.c
*
* Copyright (C) 2017 Amlogic, Inc. 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.
*
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include "hdmirx_ext_drv.h"
#include "hdmirx_ext_hw_iface.h"
#include "hdmirx_ext_attrs.h"
#include "vdin_iface.h"
#include "platform_iface.h"
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
static ssize_t hdmirx_ext_debug_print_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "hdmirx_ext_debug_print: %d\n",
hdmirx_ext_debug_print);
}
static ssize_t hdmirx_ext_debug_print_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int temp = 0;
int ret;
ret = kstrtouint(buf, 10, &temp);
hdmirx_ext_debug_print = temp;
pr_info("set hdmirx_ext_debug_print: %d\n", temp);
return count;
}
static ssize_t hdmirx_ext_info_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct hdmirx_ext_drv_s *hdrv = hdmirx_ext_get_driver();
return sprintf(buf, "hdmirx_ext_info:\n"
"name: %s\n"
"state: %d\n"
"hw_i2c_addr: 0x%02x\n"
"hw_i2c_bus_index: %d\n"
"hw_en_gpio: %s\n"
"hw_reset_gpio: %s\n"
"hw_pinmux_flag: %d\n"
"vdin_sel : %d\n"
"bt656_sel : %d\n"
"vdin_started: %d\n",
hdrv->name, hdrv->state,
hdrv->hw.i2c_addr, hdrv->hw.i2c_bus_index,
(hdrv->hw.en_gpio.flag) ?
hdrv->hw.en_gpio.name : "null",
(hdrv->hw.reset_gpio.flag) ?
hdrv->hw.reset_gpio.name : "null",
hdrv->hw.pinmux_flag,
hdrv->vdin.vdin_sel,
hdrv->vdin.bt656_sel,
hdrv->vdin.started);
}
static ssize_t hdmirx_ext_debug_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "todo: debug iface for read\n");
}
static ssize_t hdmirx_ext_debug_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
__hw_debug((char *)buf);
return count;
}
static ssize_t hdmirx_ext_port_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
char port = 0xff;
port = __hw_get_input_port();
return sprintf(buf, "current hdmirx_ext input port = %d\n", port);
}
static ssize_t hdmirx_ext_port_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
unsigned char port = 0;
unsigned long temp;
int ret;
ret = kstrtoul(buf, 10, &temp);
port = (unsigned char)temp;
if (port < 4) {
__hw_set_input_port(port);
pr_info("set hdmirx_ext input port = %d\n", port);
}
return count;
}
static ssize_t hdmirx_ext_enable_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct hdmirx_ext_drv_s *hdrv = hdmirx_ext_get_driver();
return sprintf(buf, "hdmirx_ext tvin enable = %d\n", hdrv->user_cmd);
}
static ssize_t hdmirx_ext_enable_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct hdmirx_ext_drv_s *hdrv = hdmirx_ext_get_driver();
int argn = 0;
char *p = NULL, *para = NULL;
char *argv[5] = {NULL, NULL, NULL, NULL, NULL};
char str[3] = {' ', '\n', '\0'};
unsigned int mode = 0, enable = 0;
/*unsigned int height = 0, width = 0, frame_rate = 0, field_flag = 0;*/
p = kstrdup(buf, GFP_KERNEL);
while (1) {
para = strsep(&p, str);
if (para == NULL)
break;
if (*para == '\0')
continue;
argv[argn++] = para;
}
/*pr_info("argn = %d, \"%s\", \"%s\", \"%s\", \"%s\", \"%s\"\n",
* argn, argv[0], argv[1], argv[2], argv[3], argv[4]);
*/
if (!strcmp(argv[0], "0")) { /* disable */
enable = 0;
} else if (!strcmp(argv[0], "1")) {
/* enable, driver will trigger to vdin-stop */
enable = 1;
} else if (!strcmp(argv[0], "2")) {
/* enable, driver will trigger to vdin-start */
enable = 2;
} else if (!strcmp(argv[0], "3")) {
/* enable, driver will trigger to vdin-start/vdin-stop */
enable = 3;
} else if (!strcmp(argv[0], "4")) {
/* enable, driver will not trigger to vdin-start/vdin-stop */
enable = 4;
} else {
/* enable, driver will trigger specified mode */
enable = 0xff;
}
hdrv->user_cmd = enable;
/*if ((enable==1) && (argn!=5) && (argn!=1)) {
* pr_info("invalid parameters to enable cmd !\n");
* kfree(p);
* return count;
*}
*/
if ((enable == 0) && (hdrv->vdin.started == 1)) {
hdmirx_ext_stop_vdin();
pr_info("hdmirx_ext disable vdin\n");
} else if (((enable == 1) || (enable == 2) ||
(enable == 3) || (enable == 4)) && (hdrv->vdin.started == 0)) {
mode = __hw_get_video_mode();
hdmirx_ext_start_vdin_mode(mode);
pr_info("hdmirx_ext enable(0x%x) vdin, mode = %d\n",
enable, mode);
} else if ((enable == 0xff) && (hdrv->vdin.started == 0)) {
mode = __plat_get_video_mode_by_name(argv[0]);
hdmirx_ext_start_vdin_mode(mode);
pr_info("hdmirx_ext enable(0x%x) vdin, mode = %d\n",
enable, mode);
} else {
pr_info("error: enable=0x%x, mode=%d, vdin_started=%d\n",
enable, mode, hdrv->vdin.started);
}
kfree(p);
return count;
}
static ssize_t hdmirx_ext_video_mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
unsigned int mode = 0xff;
char hdmi_mode_str[16], *mode_str;
unsigned char value;
value = __hw_is_hdmi_mode();
memset(hdmi_mode_str, 0x00, 16);
strcpy(hdmi_mode_str, (value == 0) ? "DVI:" : "HDMI:");
mode = __hw_get_video_mode();
mode_str = __plat_get_video_mode_name(mode);
if (strcmp(mode_str, "invalid") != 0) {
if (strlen(mode_str) <
(sizeof(hdmi_mode_str) - strlen(hdmi_mode_str)))
strcat(hdmi_mode_str, mode_str);
} else {
if (strlen(mode_str) < sizeof(hdmi_mode_str))
strcpy(hdmi_mode_str, mode_str);
}
return sprintf(buf, "%s\n", hdmi_mode_str);
}
static ssize_t hdmirx_ext_cable_status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct hdmirx_ext_drv_s *hdrv = hdmirx_ext_get_driver();
hdrv->status.cable = __hw_get_cable_status();
return sprintf(buf, "%d\n", hdrv->status.cable);
}
static ssize_t hdmirx_ext_signal_status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct hdmirx_ext_drv_s *hdrv = hdmirx_ext_get_driver();
hdrv->status.signal = __hw_get_cable_status();
return sprintf(buf, "%d\n", hdrv->status.signal);
}
static ssize_t hdmirx_ext_audio_sr_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int audio_sr;
static const char * const audio_sr_array[] = {
"44.1 kHz", /* 0x0 */
"Not indicated", /* 0x1 */
"48 kHz", /* 0x2 */
"32 kHz", /* 0x3 */
"22.05 kHz", /* 0x4 */
"reserved", /* 0x5 */
"24 kHz", /* 0x6 */
"reserved", /* 0x7 */
"88.2 kHz", /* 0x8 */
"768 kHz (192*4)", /* 0x9 */
"96 kHz", /* 0xa */
"reserved", /* 0xb */
"176.4 kHz", /* 0xc */
"reserved", /* 0xd */
"192 kHz", /* 0xe */
"reserved" /* 0xf */
};
audio_sr = __hw_get_audio_sample_rate();
if ((audio_sr < 0) ||
(audio_sr >= (sizeof(audio_sr_array)/sizeof(char *))))
audio_sr = 0;
return sprintf(buf, "%s\n", audio_sr_array[audio_sr]);
}
static DEVICE_ATTR(print, 0644,
hdmirx_ext_debug_print_show, hdmirx_ext_debug_print_store);
static DEVICE_ATTR(info, 0444, hdmirx_ext_info_show, NULL);
static DEVICE_ATTR(debug, 0644, hdmirx_ext_debug_show, hdmirx_ext_debug_store);
static DEVICE_ATTR(port, 0644, hdmirx_ext_port_show, hdmirx_ext_port_store);
static DEVICE_ATTR(enable, 0644,
hdmirx_ext_enable_show, hdmirx_ext_enable_store);
static DEVICE_ATTR(video_mode, 0444, hdmirx_ext_video_mode_show, NULL);
static DEVICE_ATTR(cable_status, 0444, hdmirx_ext_cable_status_show, NULL);
static DEVICE_ATTR(signal_status, 0444, hdmirx_ext_signal_status_show, NULL);
static DEVICE_ATTR(audio_sample_rate, 0444, hdmirx_ext_audio_sr_show, NULL);
int hdmirx_ext_create_device_attrs(struct device *pdevice)
{
int ret = -1;
ret = device_create_file(pdevice, &dev_attr_print);
ret |= device_create_file(pdevice, &dev_attr_info);
ret |= device_create_file(pdevice, &dev_attr_debug);
ret |= device_create_file(pdevice, &dev_attr_port);
ret |= device_create_file(pdevice, &dev_attr_enable);
ret |= device_create_file(pdevice, &dev_attr_video_mode);
ret |= device_create_file(pdevice, &dev_attr_cable_status);
ret |= device_create_file(pdevice, &dev_attr_signal_status);
ret |= device_create_file(pdevice, &dev_attr_audio_sample_rate);
return ret;
}
void hdmirx_ext_destroy_device_attrs(struct device *pdevice)
{
device_remove_file(pdevice, &dev_attr_print);
device_remove_file(pdevice, &dev_attr_info);
device_remove_file(pdevice, &dev_attr_debug);
device_remove_file(pdevice, &dev_attr_port);
device_remove_file(pdevice, &dev_attr_enable);
device_remove_file(pdevice, &dev_attr_video_mode);
device_remove_file(pdevice, &dev_attr_cable_status);
device_remove_file(pdevice, &dev_attr_signal_status);
device_remove_file(pdevice, &dev_attr_audio_sample_rate);
}