123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * Copyright (c) 2017-2021, The Linux Foundation. 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 version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * 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/module.h>
- #include <linux/kernel.h>
- #include <linux/device.h>
- #include <drm/drm_edid.h>
- #include <linux/string.h>
- #if defined(CONFIG_SECDP_BIGDATA)
- #include <linux/secdp_bigdata.h>
- #endif
- #include "dp_link.h"
- #include "dp_panel.h"
- #include "dp_power.h"
- #include "dp_catalog.h"
- #include "dp_debug.h"
- #include "dp_display.h"
- #include "secdp.h"
- #include "secdp_sysfs.h"
- #include "sde_edid_parser.h"
- #include "secdp_unit_test.h"
- enum secdp_unit_test_cmd {
- SECDP_UTCMD_EDID_PARSE = 0,
- };
- struct secdp_sysfs_private {
- struct device *dev;
- struct dp_parser *parser;
- struct dp_panel *panel;
- struct dp_power *power;
- struct dp_link *link;
- struct dp_ctrl *ctrl;
- struct dp_catalog *catalog;
- struct secdp_misc *sec;
- struct secdp_sysfs dp_sysfs;
- enum secdp_unit_test_cmd test_cmd;
- };
- static inline char *secdp_utcmd_to_str(u32 cmd_type)
- {
- switch (cmd_type) {
- case SECDP_UTCMD_EDID_PARSE:
- return SECDP_ENUM_STR(SECDP_UTCMD_EDID_PARSE);
- default:
- return "unknown";
- }
- }
- /** check if buf has range('-') format
- * @buf buf to be checked
- * @size buf size
- * @retval 0 if args are ok, -1 if '-' included
- */
- static int secdp_check_store_args(const char *buf, size_t size)
- {
- int ret;
- if (strnchr(buf, size, '-')) {
- DP_ERR("range is forbidden!\n");
- ret = -1;
- goto exit;
- }
- ret = 0;
- exit:
- return ret;
- }
- static struct secdp_sysfs_private *secdp_get_sysfs_private(struct class *class)
- {
- struct secdp_sysfs *dp_sysfs;
- dp_sysfs = container_of(class, struct secdp_sysfs, dp_class);
- return container_of(dp_sysfs, struct secdp_sysfs_private, dp_sysfs);
- }
- #if defined(CONFIG_SECDP_FACTORY_DPSWITCH_TEST)
- static ssize_t dp_sbu_sw_sel_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- int sbu_sw_sel, sbu_sw_oe, val[10] = {0,};
- if (secdp_check_store_args(buf, size)) {
- DP_ERR("args error!\n");
- goto exit;
- }
- get_options(buf, ARRAY_SIZE(val), val);
- sbu_sw_sel = val[1];
- sbu_sw_oe = val[2];
- DP_INFO("sw_sel:%d sw_oe:%d\n", sbu_sw_sel, sbu_sw_oe);
- sysfs = secdp_get_sysfs_private(class);
- if (sbu_sw_oe == 0/*on*/)
- secdp_config_gpios_factory(sysfs->power, sbu_sw_sel, true);
- else if (sbu_sw_oe == 1/*off*/)
- secdp_config_gpios_factory(sysfs->power, sbu_sw_sel, false);
- else
- DP_ERR("unknown sw_oe %d\n", sbu_sw_oe);
- exit:
- return size;
- }
- static CLASS_ATTR_WO(dp_sbu_sw_sel);
- #endif
- #define SECDP_DEX_ADAPTER_SKIP "SkipAdapterCheck"
- #define SECDP_EXTDISP_OFF "ExtDispOff"
- static ssize_t dex_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- struct secdp_misc *sec;
- struct secdp_dex *dex;
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- sec = sysfs->sec;
- dex = &sec->dex;
- if (!secdp_get_cable_status() || !secdp_get_hpd_status() ||
- secdp_get_poor_connection_status(sysfs->link) ||
- !secdp_get_link_train_status(sysfs->ctrl)) {
- DP_INFO("cable is out\n");
- dex->prev = dex->curr = dex->status = DEX_DISABLED;
- }
- DP_INFO("prev:%d curr:%d status:%d %s:%d %s:%d\n",
- dex->prev, dex->curr, dex->status,
- SECDP_DEX_ADAPTER_SKIP, dex->adapter_check_skip,
- SECDP_EXTDISP_OFF, sec->extdisp_off);
- #if 1//org
- rc = scnprintf(buf, PAGE_SIZE, "%d\n", dex->status);
- #else//.TODO: DeX team needs to check if this chnage is good to parse
- rc = scnprintf(buf, PAGE_SIZE, "%d,%s:%d,%s:%d\n", dex->status,
- SECDP_DEX_ADAPTER_SKIP, dex->adapter_check_skip,
- SECDP_EXTDISP_OFF, sec->extdisp_off);
- #endif
- if (dex->status == DEX_MODE_CHANGING)
- dex->status = dex->curr;
- return rc;
- }
- /*
- * assume that 1 HMD device has name(14),vid(4),pid(4) each, then
- * max 32 HMD devices(name,vid,pid) need 806 bytes including TAG, NUM, comba
- */
- #define MAX_DEX_STORE_LEN 1024
- static ssize_t dex_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- struct secdp_misc *sec;
- struct secdp_dex *dex;
- struct secdp_pdic_noti *pdic_noti;
- char *p, *tok, str[MAX_DEX_STORE_LEN] = {0,};
- int len, val[4] = {0,};
- int setting_ui; /* setting has Dex mode? if yes, 1. otherwise 0 */
- int run; /* dex is running now? if yes, 1. otherwise 0 */
- sysfs = secdp_get_sysfs_private(class);
- sec = sysfs->sec;
- dex = &sec->dex;
- pdic_noti = &sec->pdic_noti;
- if (secdp_get_lpm_mode(sec)) {
- DP_INFO("LPM mode, skip\n");
- goto exit;
- }
- if (size >= MAX_DEX_STORE_LEN) {
- DP_ERR("too long args! %lu\n", size);
- goto exit;
- }
- if (secdp_check_store_args(buf, size)) {
- DP_ERR("args error!\n");
- goto exit;
- }
- mutex_lock(&sec->hmd.lock);
- memcpy(str, buf, size);
- p = str;
- tok = strsep(&p, ",");
- len = strlen(tok);
- //DP_DEBUG("tok:%s len:%d\n", tok, len);
- if (len && !strncmp(DEX_TAG_HMD, tok, len)) {
- int num_hmd = 0, sz = 0, ret;
- tok = strsep(&p, ",");
- if (!tok) {
- DP_ERR("wrong input!\n");
- mutex_unlock(&sec->hmd.lock);
- goto exit;
- }
- sz = strlen(tok);
- ret = kstrtouint(tok, 10, &num_hmd);
- DP_DEBUG("[%s] num:%d sz:%d ret:%d\n", DEX_TAG_HMD,
- num_hmd, sz, ret);
- if (!ret) {
- ret = secdp_store_hmd_dev(sysfs->sec, str + (len + sz + 2),
- size - (len + sz + 2), num_hmd);
- }
- if (ret)
- size = ret; /* error! */
- mutex_unlock(&sec->hmd.lock);
- goto exit;
- }
- mutex_unlock(&sec->hmd.lock);
- if (len && !strncmp(SECDP_DEX_ADAPTER_SKIP, tok, len)) {
- int param = 0, sz = 0, ret;
- tok = strsep(&p, ",");
- if (!tok) {
- DP_ERR("wrong input!\n");
- goto exit;
- }
- sz = strlen(tok);
- ret = kstrtouint(tok, 2, ¶m);
- if (ret) {
- DP_ERR("error %d\n", ret);
- goto exit;
- }
- DP_DEBUG("[%s] param:%d sz:%d ret:%d\n", SECDP_DEX_ADAPTER_SKIP,
- param, sz, ret);
- dex->adapter_check_skip = (!param) ? false : true;
- goto exit;
- }
- if (len && !strncmp(SECDP_EXTDISP_OFF, tok, len)) {
- int param = 0, sz = 0, ret;
- tok = strsep(&p, ",");
- if (!tok) {
- DP_ERR("wrong input!\n");
- goto exit;
- }
- sz = strlen(tok);
- ret = kstrtouint(tok, 2, ¶m);
- if (ret) {
- DP_ERR("error %d\n", ret);
- goto exit;
- }
- DP_DEBUG("[%s] param:%d sz:%d ret:%d\n", SECDP_EXTDISP_OFF,
- param, sz, ret);
- sec->extdisp_off = (!param) ? false : true;
- if (sec->extdisp_off)
- secdp_extdisp_off(sec);
- else
- secdp_extdisp_on(sec);
- goto exit;
- }
- get_options(buf, ARRAY_SIZE(val), val);
- setting_ui = (val[1] & 0xf0) >> 4;
- run = (val[1] & 0x0f);
- DP_INFO("0x%02x setting_ui:%d run:%d cable:%d\n", val[1],
- setting_ui, run, sec->cable_connected);
- dex->setting_ui = setting_ui;
- dex->status = dex->curr = run;
- mutex_lock(&sec->notifier_lock);
- if (!pdic_noti->registered) {
- int rc;
- /* cancel immediately */
- rc = cancel_delayed_work(&pdic_noti->reg_work);
- DP_DEBUG("notifier get registered by dex, cancel:%d\n", rc);
- destroy_delayed_work_on_stack(&pdic_noti->reg_work);
- /* register */
- rc = secdp_pdic_noti_register_ex(sec, false);
- if (rc)
- DP_ERR("noti register fail %d\n", rc);
- mutex_unlock(&sec->notifier_lock);
- goto exit;
- }
- mutex_unlock(&sec->notifier_lock);
- if (!secdp_get_cable_status() || !secdp_get_hpd_status() ||
- secdp_get_poor_connection_status(sysfs->link) ||
- !secdp_get_link_train_status(sysfs->ctrl)) {
- DP_INFO("cable is out\n");
- dex->prev = dex->curr = dex->status = DEX_DISABLED;
- goto exit;
- }
- if (sec->hpd.noti_deferred) {
- secdp_send_deferred_hpd_noti(sec);
- dex->prev = dex->setting_ui;
- goto exit;
- }
- if (dex->curr == dex->prev) {
- DP_INFO("dex is already %s\n",
- (dex->curr == DEX_ENABLED) ? "enabled" :
- ((dex->curr == DEX_DISABLED) ? "disabled" : "changing"));
- goto exit;
- }
- if (dex->curr != dex->setting_ui) {
- DP_INFO("curr and setting_ui are different %d %d\n",
- dex->curr, dex->setting_ui);
- goto exit;
- }
- #if defined(CONFIG_SECDP_BIGDATA)
- if (run)
- secdp_bigdata_save_item(BD_DP_MODE, "DEX");
- else
- secdp_bigdata_save_item(BD_DP_MODE, "MIRROR");
- #endif
- if (sec->dex.res == DEX_RES_NOT_SUPPORT) {
- DP_DEBUG("this dongle does not support dex\n");
- goto exit;
- }
- if (!secdp_check_reconnect(sysfs->sec)) {
- DP_INFO("not need reconnect\n");
- goto exit;
- }
- secdp_reconnect(sysfs->sec);
- dex->prev = run;
- exit:
- return size;
- }
- static CLASS_ATTR_RW(dex);
- static ssize_t dex_ver_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- struct secdp_adapter *adapter;
- int rc;
- sysfs = secdp_get_sysfs_private(class);
- adapter = &sysfs->sec->adapter;
- DP_INFO("branch revision: HW(0x%X),SW(0x%X,0x%X)\n",
- adapter->fw_ver[0], adapter->fw_ver[1], adapter->fw_ver[2]);
- rc = scnprintf(buf, PAGE_SIZE, "%02X%02X\n",
- adapter->fw_ver[1], adapter->fw_ver[2]);
- return rc;
- }
- static CLASS_ATTR_RO(dex_ver);
- /* note: needs test once wifi is fixed */
- static ssize_t monitor_info_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- struct dp_panel *panel;
- struct sde_edid_ctrl *edid_ctrl = NULL;
- struct edid *edid = NULL;
- short prod_id = 0;
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- panel = sysfs->panel;
- edid_ctrl = panel->edid_ctrl;
- if (!edid_ctrl) {
- DP_ERR("unable to find edid_ctrl\n");
- goto exit;
- }
- edid = edid_ctrl->edid;
- if (!edid) {
- DP_ERR("unable to find edid\n");
- goto exit;
- }
- prod_id |= (edid->prod_code[0] << 8) | (edid->prod_code[1]);
- DP_DEBUG("prod_code[0]:%02x, prod_code[1]:%02x, prod_id:%04x\n",
- edid->prod_code[0], edid->prod_code[1], prod_id);
- rc = snprintf(buf, SZ_32, "%s,0x%x,0x%x\n",
- edid_ctrl->vendor_id, prod_id, edid->serial); /* byte order? */
- exit:
- return rc;
- }
- static CLASS_ATTR_RO(monitor_info);
- #ifdef SYSFS_BW_CODE
- static ssize_t bw_code_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- struct dp_parser *parser;
- struct dp_link *link;
- struct dp_link_params *params;
- int val = 0, rc = 0;
- DP_ENTER("\n");
- sysfs = secdp_get_sysfs_private(class);
- parser = sysfs->parser;
- if (!parser->rf_tx_backoff) {
- DP_DEBUG("RF TX backoff not supported\n");
- goto exit;
- }
- if (!secdp_get_cable_status())
- goto exit;
- if (!secdp_get_hpd_status())
- goto exit;
- link = sysfs->link;
- params = &link->link_params;
- switch(params->bw_code) {
- case DP_LINK_BW_1_62:
- val = 1;
- break;
- case DP_LINK_BW_2_7:
- val = 2;
- break;
- case DP_LINK_BW_5_4:
- val = 4;
- break;
- case DP_LINK_BW_8_1:
- val = 8;
- break;
- default:
- DP_INFO("unknown bw_code %d\n", params->bw_code);
- val = 0;
- break;
- }
- DP_INFO("bw %d\n", val);
- exit:
- rc = snprintf(buf, SZ_32, "%d\n", val);
- return rc;
- }
- static CLASS_ATTR_RO(bw_code);
- #endif
- #if defined(CONFIG_SECDP_BIGDATA)
- static ssize_t dp_error_info_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- return _secdp_bigdata_show(class, attr, buf);
- }
- static ssize_t dp_error_info_store(struct class *dev,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- return _secdp_bigdata_store(dev, attr, buf, size);
- }
- static CLASS_ATTR_RW(dp_error_info);
- #endif
- #ifdef SECDP_SELF_TEST
- static struct secdp_sef_test_item g_self_test[] = {
- {DP_ENUM_STR(ST_CLEAR_CMD), .arg_cnt = 0, .arg_str = "clear all configurations"},
- {DP_ENUM_STR(ST_LANE_CNT), .arg_cnt = 1, .arg_str = "lane_count: 1 = 1 lane, 2 = 2 lane, 4 = 4 lane, 555 = disable"},
- {DP_ENUM_STR(ST_LINK_RATE), .arg_cnt = 1, .arg_str = "link_rate: 1 = 1.62G , 2 = 2.7G, 3 = 5.4G, 555 = disable"},
- {DP_ENUM_STR(ST_CONNECTION_TEST), .arg_cnt = 1, .arg_str = "reconnection time(sec) : range = 5 ~ 50, 555 = disable"},
- {DP_ENUM_STR(ST_HDCP_TEST), .arg_cnt = 1, .arg_str = "hdcp on/off time(sec): range = 5 ~ 50, 555 = disable"},
- {DP_ENUM_STR(ST_PREEM_TUN), .arg_cnt = 16, .arg_str = "pre-emphasis calibration value, 555 = disable"},
- {DP_ENUM_STR(ST_VOLTAGE_TUN), .arg_cnt = 16, .arg_str = "voltage-level calibration value, 555 = disable"},
- };
- int secdp_self_test_status(int cmd)
- {
- if (cmd >= ST_MAX)
- return -EINVAL;
- if (g_self_test[cmd].enabled) {
- DP_INFO("%s: %s\n", g_self_test[cmd].cmd_str,
- g_self_test[cmd].enabled ? "true" : "false");
- }
- return g_self_test[cmd].enabled ? g_self_test[cmd].arg_cnt : -1;
- }
- int *secdp_self_test_get_arg(int cmd)
- {
- return g_self_test[cmd].arg;
- }
- #if 0
- void secdp_self_register_clear_func(int cmd, void (*func)(void))
- {
- if (cmd >= ST_MAX)
- return;
- g_self_test[cmd].clear = func;
- DP_INFO("%s: clear func was registered.\n", g_self_test[cmd].cmd_str);
- }
- #endif
- static void secdp_self_test_reconnect_work(struct work_struct *work)
- {
- struct delayed_work *dw;
- struct secdp_misc *sec;
- int delay;
- static unsigned long test_cnt;
- if (!secdp_get_cable_status() || !secdp_get_hpd_status()) {
- DP_INFO("cable is out\n");
- test_cnt = 0;
- return;
- }
- dw = to_delayed_work(work);
- sec = container_of(dw, struct secdp_misc, self_test_reconnect_work);
- if (sec->self_test_reconnect_cb)
- sec->self_test_reconnect_cb(sec);
- test_cnt++;
- DP_INFO("test_cnt %lu\n", test_cnt);
- delay = g_self_test[ST_CONNECTION_TEST].arg[0];
- schedule_delayed_work(&sec->self_test_reconnect_work,
- msecs_to_jiffies(delay * 1000));
- }
- void secdp_self_test_start_reconnect(struct secdp_sysfs *dp_sysfs, void (*func)(struct secdp_misc *sec))
- {
- struct secdp_sysfs_private *sysfs;
- struct secdp_misc *sec;
- int delay;
- delay = g_self_test[ST_CONNECTION_TEST].arg[0];
- if (delay > 50 || delay < 5)
- delay = g_self_test[ST_CONNECTION_TEST].arg[0] = 10;
- DP_INFO("start reconnect test %d\n", delay);
- sysfs = container_of(dp_sysfs, struct secdp_sysfs_private, dp_sysfs);
- sec = sysfs->sec;
- sec->self_test_reconnect_cb = func;
- schedule_delayed_work(&sec->self_test_reconnect_work,
- msecs_to_jiffies(delay * 1000));
- }
- static void secdp_self_test_hdcp_test_work(struct work_struct *work)
- {
- struct delayed_work *dw;
- struct secdp_misc *sec;
- int delay;
- static unsigned long test_cnt;
- if (!secdp_get_cable_status() || !secdp_get_hpd_status()) {
- DP_INFO("cable is out\n");
- test_cnt = 0;
- return;
- }
- dw = to_delayed_work(work);
- sec = container_of(dw, struct secdp_misc, self_test_hdcp_test_work);
- if (sec->self_test_hdcp_off_cb)
- sec->self_test_hdcp_off_cb();
- msleep(3000);
- if (sec->self_test_hdcp_on_cb)
- sec->self_test_hdcp_on_cb();
- test_cnt++;
- DP_INFO("test_cnt %lu\n", test_cnt);
- delay = g_self_test[ST_HDCP_TEST].arg[0];
- schedule_delayed_work(&sec->self_test_hdcp_test_work,
- msecs_to_jiffies(delay * 1000));
- }
- void secdp_self_test_start_hdcp_test(struct secdp_sysfs *dp_sysfs,
- void (*func_on)(void), void (*func_off)(void))
- {
- struct secdp_sysfs_private *sysfs;
- struct secdp_misc *sec;
- int delay;
- delay = g_self_test[ST_HDCP_TEST].arg[0];
- if (!delay) {
- DP_INFO("hdcp test is aborted\n");
- return;
- }
- if (delay > 50 || delay < 5)
- delay = g_self_test[ST_HDCP_TEST].arg[0] = 10;
- DP_INFO("start hdcp test %d\n", delay);
- sysfs = container_of(dp_sysfs, struct secdp_sysfs_private, dp_sysfs);
- sec = sysfs->sec;
- sec->self_test_hdcp_on_cb = func_on;
- sec->self_test_hdcp_off_cb = func_off;
- schedule_delayed_work(&sec->self_test_hdcp_test_work,
- msecs_to_jiffies(delay * 1000));
- }
- static ssize_t dp_self_test_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- int i, j, rc = 0;
- for (i = 0; i < ST_MAX; i++) {
- rc += scnprintf(buf + rc, PAGE_SIZE - rc,
- "%d. %s: %s\n ==>", i,
- g_self_test[i].cmd_str, g_self_test[i].arg_str);
- if (g_self_test[i].enabled) {
- rc += scnprintf(buf + rc, PAGE_SIZE - rc,
- "current value: enabled - arg: ");
- for (j = 0; j < g_self_test[i].arg_cnt; j++) {
- rc += scnprintf(buf + rc, PAGE_SIZE - rc,
- "0x%x ", g_self_test[i].arg[j]);
- }
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "\n\n");
- } else {
- rc += scnprintf(buf + rc, PAGE_SIZE - rc,
- "current value: disabled\n\n");
- }
- }
- return rc;
- }
- static void dp_self_test_clear_func(int cmd)
- {
- int arg_cnt = (g_self_test[cmd].arg_cnt < ST_ARG_CNT) ? g_self_test[cmd].arg_cnt : ST_ARG_CNT;
- g_self_test[cmd].enabled = false;
- memset(g_self_test[cmd].arg, 0, sizeof(int) * arg_cnt);
- if (g_self_test[cmd].clear)
- g_self_test[cmd].clear();
- }
- static ssize_t dp_self_test_store(struct class *dev,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- int val[ST_ARG_CNT + 2] = {0, };
- int arg, arg_cnt, cmd, i;
- if (secdp_check_store_args(buf, size)) {
- DP_ERR("args error!\n");
- goto end;
- }
- get_options(buf, ARRAY_SIZE(val), val);
- cmd = val[1];
- arg = val[2];
- if (cmd < 0 || cmd >= ST_MAX) {
- DP_INFO("invalid cmd\n");
- goto end;
- }
- if (cmd == ST_CLEAR_CMD) {
- for (i = 1; i < ST_MAX; i++)
- dp_self_test_clear_func(i);
- DP_INFO("cmd: ST_CLEAR_CMD\n");
- goto end;
- }
- g_self_test[cmd].enabled = (arg == ST_TEST_EXIT) ? false : true;
- if (g_self_test[cmd].enabled) {
- if ((val[0] - 1) != g_self_test[cmd].arg_cnt) {
- DP_INFO("invalid param.\n");
- goto end;
- }
- arg_cnt = (g_self_test[cmd].arg_cnt < ST_ARG_CNT) ? g_self_test[cmd].arg_cnt : ST_ARG_CNT;
- memcpy(g_self_test[cmd].arg, val + 2, sizeof(int) * arg_cnt);
- } else {
- dp_self_test_clear_func(cmd);
- }
- DP_INFO("cmd: %d. %s, enable:%s\n", cmd,
- (cmd < ST_MAX) ? g_self_test[cmd].cmd_str : "null",
- (cmd < ST_MAX) ? (g_self_test[cmd].enabled ? "true" : "false") : "null");
- end:
- return size;
- }
- static CLASS_ATTR_RW(dp_self_test);
- #endif
- #if defined(CONFIG_SECDP_DBG)
- bool secdp_func_trace;
- #define SECDP_FUNC_TRACE "func_trace" //ex) echo "func_trace,1" > dp_debug
- #define SECDP_SSC_ONOFF "ssc" //ex) echo "ssc,1" > dp_debug
- static ssize_t dp_debug_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- struct secdp_misc *sec;
- struct secdp_dex *dex;
- char tmp[SZ_1K] = {0,};
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- sec = sysfs->sec;
- dex = &sec->dex;
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "==========\n");
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "[dbg] func_trace: %d\n", secdp_func_trace);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "[dex] adapter_check_skip: %d\n", dex->adapter_check_skip);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "[psm] extdisp_off: %d\n", sec->extdisp_off);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "[ssc] ssc_en: %d\n", secdp_debug_get_ssc(sec));
- secdp_show_hmd_dev(sysfs->sec, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "\n< HMD >\n%s\n", tmp);
- memset(tmp, 0, ARRAY_SIZE(tmp));
- secdp_show_phy_param(sysfs->parser, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "\n< DP-PHY >\n%s\n", tmp);
- memset(tmp, 0, ARRAY_SIZE(tmp));
- secdp_show_link_param(sysfs->link, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "\n< link params >\n%s\n", tmp);
- #if IS_ENABLED(CONFIG_COMBO_REDRIVER_PS5169)
- memset(tmp, 0, ARRAY_SIZE(tmp));
- secdp_show_ps5169_param(sysfs->parser, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "\n< PS5169 EQ0/EQ1 >\n%s\n", tmp);
- #endif
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "==========\n");
- return rc;
- }
- static ssize_t dp_debug_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- struct secdp_misc *sec;
- char str[MAX_DEX_STORE_LEN] = {0,}, *p, *tok;
- int len, val[10] = {0, };
- if (size >= MAX_DEX_STORE_LEN) {
- DP_ERR("too long args! %lu\n", size);
- goto exit;
- }
- if (secdp_check_store_args(buf, size)) {
- DP_ERR("args error!\n");
- goto exit;
- }
- sysfs = secdp_get_sysfs_private(class);
- sec = sysfs->sec;
- get_options(buf, ARRAY_SIZE(val), val);
- memcpy(str, buf, size);
- p = str;
- tok = strsep(&p, ",");
- if (!p) {
- DP_ERR("error: no token found\n");
- goto exit;
- }
- len = strlen(tok);
- if (!len) {
- DP_ERR("error: token len is zero\n");
- goto exit;
- }
- DP_DEBUG("tok:%s, len:%d\n", tok, len);
- if (len && !strncmp(SECDP_FUNC_TRACE, tok, len)) {
- int param = 0, sz = 0, ret;
- tok = strsep(&p, ",");
- if (!tok) {
- DP_ERR("wrong input!\n");
- goto exit;
- }
- sz = strlen(tok);
- ret = kstrtouint(tok, 2, ¶m);
- if (ret) {
- DP_ERR("error:%d\n", ret);
- goto exit;
- }
- DP_DEBUG("[%s] param:%d sz:%d ret:%d\n", SECDP_FUNC_TRACE,
- param, sz, ret);
- secdp_func_trace = param ? 1 : 0;
- goto exit;
- }
- if (len && !strncmp(SECDP_SSC_ONOFF, tok, len)) {
- int param = 0, sz = 0, ret;
- tok = strsep(&p, ",");
- if (!tok) {
- DP_ERR("wrong input!\n");
- goto exit;
- }
- sz = strlen(tok);
- ret = kstrtouint(tok, 2, ¶m);
- if (ret) {
- DP_ERR("error:%d\n", ret);
- goto exit;
- }
- DP_DEBUG("[%s] param:%d sz:%d ret:%d\n", SECDP_SSC_ONOFF,
- param, sz, ret);
- secdp_debug_set_ssc(sec, param ? true : false);
- goto exit;
- }
- exit:
- return size;
- }
- static CLASS_ATTR_RW(dp_debug);
- static ssize_t dp_unit_test_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- int rc, cmd;
- bool res = false;
- sysfs = secdp_get_sysfs_private(class);
- cmd = sysfs->test_cmd;
- DP_INFO("test_cmd: %s\n", secdp_utcmd_to_str(cmd));
- switch (cmd) {
- case SECDP_UTCMD_EDID_PARSE:
- res = secdp_unit_test_edid_parse();
- break;
- default:
- DP_INFO("invalid test_cmd: %d\n", cmd);
- break;
- }
- rc = scnprintf(buf, 3, "%d\n", res ? 1 : 0);
- return rc;
- }
- static ssize_t dp_unit_test_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- int val[10] = {0, };
- if (secdp_check_store_args(buf, size)) {
- DP_ERR("args error!\n");
- goto exit;
- }
- sysfs = secdp_get_sysfs_private(class);
- get_options(buf, ARRAY_SIZE(val), val);
- sysfs->test_cmd = val[1];
- DP_INFO("test_cmd: %d...%s\n", sysfs->test_cmd,
- secdp_utcmd_to_str(sysfs->test_cmd));
- exit:
- return size;
- }
- static CLASS_ATTR_RW(dp_unit_test);
- static ssize_t dp_aux_cfg_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_1K] = {0,};
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- secdp_aux_cfg_show(sysfs->parser, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "\n< AUX cfg >\n%s\n", tmp);
- return rc;
- }
- static ssize_t dp_aux_cfg_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_1K] = {0,};
- sysfs = secdp_get_sysfs_private(class);
- memcpy(tmp, buf, min(ARRAY_SIZE(tmp) - 1, size));
- secdp_aux_cfg_store(sysfs->parser, tmp);
- return size;
- }
- static CLASS_ATTR_RW(dp_aux_cfg);
- static ssize_t dp_preshoot_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_64] = {0,};
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- secdp_catalog_preshoot_show(sysfs->catalog, tmp);
- rc = snprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
- return rc;
- }
- static ssize_t dp_preshoot_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_64] = {0,};
- int len = min(sizeof(tmp), size);
- if (!len || len >= SZ_64) {
- DP_ERR("wrong length! %d\n", len);
- goto end;
- }
- sysfs = secdp_get_sysfs_private(class);
- memcpy(tmp, buf, len);
- tmp[SZ_64 - 1] = '\0';
- secdp_catalog_preshoot_store(sysfs->catalog, tmp);
- end:
- return size;
- }
- static CLASS_ATTR_RW(dp_preshoot);
- static ssize_t dp_hbr2_3_voltage_swing_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_1K] = {0,};
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- secdp_parse_vxpx_show(sysfs->parser, DP_LR_HBR2_3, DP_PARAM_VX, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
- return rc;
- }
- static ssize_t dp_hbr2_3_voltage_swing_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_64] = {0,};
- int len = min(sizeof(tmp), size);
- if (!len || len >= SZ_64) {
- DP_ERR("wrong length! %d\n", len);
- goto end;
- }
- sysfs = secdp_get_sysfs_private(class);
- memcpy(tmp, buf, len);
- tmp[SZ_64 - 1] = '\0';
- secdp_parse_vxpx_store(sysfs->parser, DP_LR_HBR2_3, DP_PARAM_VX, tmp);
- end:
- return size;
- }
- static CLASS_ATTR_RW(dp_hbr2_3_voltage_swing);
- static ssize_t dp_hbr2_3_pre_emphasis_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_1K] = {0,};
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- secdp_parse_vxpx_show(sysfs->parser, DP_LR_HBR2_3, DP_PARAM_PX, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
- return rc;
- }
- static ssize_t dp_hbr2_3_pre_emphasis_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_64] = {0,};
- int len = min(sizeof(tmp), size);
- if (!len || len >= SZ_64) {
- DP_ERR("wrong length! %d\n", len);
- goto end;
- }
- sysfs = secdp_get_sysfs_private(class);
- memcpy(tmp, buf, len);
- tmp[SZ_64 - 1] = '\0';
- secdp_parse_vxpx_store(sysfs->parser, DP_LR_HBR2_3, DP_PARAM_PX, tmp);
- end:
- return size;
- }
- static CLASS_ATTR_RW(dp_hbr2_3_pre_emphasis);
- static ssize_t dp_hbr_rbr_voltage_swing_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_1K] = {0,};
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- secdp_parse_vxpx_show(sysfs->parser, DP_LR_HBR_RBR, DP_PARAM_VX, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
- return rc;
- }
- static ssize_t dp_hbr_rbr_voltage_swing_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_64] = {0,};
- int len = min(sizeof(tmp), size);
- if (!len || len >= SZ_64) {
- DP_ERR("wrong length! %d\n", len);
- goto end;
- }
- sysfs = secdp_get_sysfs_private(class);
- memcpy(tmp, buf, len);
- tmp[SZ_64 - 1] = '\0';
- secdp_parse_vxpx_store(sysfs->parser, DP_LR_HBR_RBR, DP_PARAM_VX, tmp);
- end:
- return size;
- }
- static CLASS_ATTR_RW(dp_hbr_rbr_voltage_swing);
- static ssize_t dp_hbr_rbr_pre_emphasis_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_1K] = {0,};
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- secdp_parse_vxpx_show(sysfs->parser, DP_LR_HBR_RBR, DP_PARAM_PX, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
- return rc;
- }
- static ssize_t dp_hbr_rbr_pre_emphasis_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_64] = {0,};
- int len = min(sizeof(tmp), size);
- if (!len || len >= SZ_64) {
- DP_ERR("wrong length! %d\n", len);
- goto end;
- }
- sysfs = secdp_get_sysfs_private(class);
- memcpy(tmp, buf, len);
- tmp[SZ_64 - 1] = '\0';
- secdp_parse_vxpx_store(sysfs->parser, DP_LR_HBR_RBR, DP_PARAM_PX, tmp);
- end:
- return size;
- }
- static CLASS_ATTR_RW(dp_hbr_rbr_pre_emphasis);
- static ssize_t dp_pref_skip_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- int skip, rc;
- DP_ENTER("\n");
- sysfs = secdp_get_sysfs_private(class);
- skip = sysfs->sec->debug.prefer_check_skip;
- rc = snprintf(buf, SZ_8, "%d\n", skip);
- return rc;
- }
- static ssize_t dp_pref_skip_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- int i, val[30] = {0, };
- if (secdp_check_store_args(buf, size)) {
- DP_ERR("args error!\n");
- goto exit;
- }
- DP_DEBUG("size:%d\n", (int)size);
- get_options(buf, ARRAY_SIZE(val), val);
- for (i = 0; i < 16; i = i + 4) {
- DP_DEBUG("%02x,%02x,%02x,%02x\n",
- val[i+1], val[i+2], val[i+3], val[i+4]);
- }
- sysfs = secdp_get_sysfs_private(class);
- sysfs->sec->debug.prefer_check_skip = val[1];
- exit:
- return size;
- }
- static CLASS_ATTR_RW(dp_pref_skip);
- static ssize_t dp_pref_ratio_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- int ratio, rc;
- DP_ENTER("\n");
- sysfs = secdp_get_sysfs_private(class);
- ratio = sysfs->sec->prefer.ratio;
- rc = snprintf(buf, SZ_8, "%d\n", ratio);
- return rc;
- }
- static ssize_t dp_pref_ratio_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- int i, val[30] = {0, };
- if (secdp_check_store_args(buf, size)) {
- DP_ERR("args error!\n");
- goto exit;
- }
- DP_DEBUG("size:%d\n", (int)size);
- get_options(buf, ARRAY_SIZE(val), val);
- for (i = 0; i < 16; i = i + 4) {
- DP_DEBUG("%02x,%02x,%02x,%02x\n",
- val[i+1], val[i+2], val[i+3], val[i+4]);
- }
- sysfs = secdp_get_sysfs_private(class);
- sysfs->sec->prefer.ratio = val[1];
- exit:
- return size;
- }
- static CLASS_ATTR_RW(dp_pref_ratio);
- #if IS_ENABLED(CONFIG_COMBO_REDRIVER_PS5169)
- static ssize_t dp_ps5169_rbr_eq0_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_1K] = {0,};
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- secdp_parse_ps5169_show(sysfs->parser, DP_PS5169_EQ0, DP_PS5169_RATE_RBR, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
- return rc;
- }
- static ssize_t dp_ps5169_rbr_eq0_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_64] = {0,};
- int len = min(sizeof(tmp), size);
- if (!len || len >= SZ_64) {
- DP_ERR("wrong length! %d\n", len);
- goto end;
- }
- sysfs = secdp_get_sysfs_private(class);
- memcpy(tmp, buf, len);
- tmp[SZ_64 - 1] = '\0';
- secdp_parse_ps5169_store(sysfs->parser, DP_PS5169_EQ0, DP_PS5169_RATE_RBR, tmp);
- end:
- return size;
- }
- static CLASS_ATTR_RW(dp_ps5169_rbr_eq0);
- static ssize_t dp_ps5169_rbr_eq1_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_1K] = {0,};
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- secdp_parse_ps5169_show(sysfs->parser, DP_PS5169_EQ1, DP_PS5169_RATE_RBR, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
- return rc;
- }
- static ssize_t dp_ps5169_rbr_eq1_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_64] = {0,};
- int len = min(sizeof(tmp), size);
- if (!len || len >= SZ_64) {
- DP_ERR("wrong length! %d\n", len);
- goto end;
- }
- sysfs = secdp_get_sysfs_private(class);
- memcpy(tmp, buf, len);
- tmp[SZ_64 - 1] = '\0';
- secdp_parse_ps5169_store(sysfs->parser, DP_PS5169_EQ1, DP_PS5169_RATE_RBR, tmp);
- end:
- return size;
- }
- static CLASS_ATTR_RW(dp_ps5169_rbr_eq1);
- static ssize_t dp_ps5169_hbr_eq0_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_1K] = {0,};
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- secdp_parse_ps5169_show(sysfs->parser, DP_PS5169_EQ0, DP_PS5169_RATE_HBR, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
- return rc;
- }
- static ssize_t dp_ps5169_hbr_eq0_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_64] = {0,};
- int len = min(sizeof(tmp), size);
- if (!len || len >= SZ_64) {
- DP_ERR("wrong length! %d\n", len);
- goto end;
- }
- sysfs = secdp_get_sysfs_private(class);
- memcpy(tmp, buf, len);
- tmp[SZ_64 - 1] = '\0';
- secdp_parse_ps5169_store(sysfs->parser, DP_PS5169_EQ0, DP_PS5169_RATE_HBR, tmp);
- end:
- return size;
- }
- static CLASS_ATTR_RW(dp_ps5169_hbr_eq0);
- static ssize_t dp_ps5169_hbr_eq1_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_1K] = {0,};
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- secdp_parse_ps5169_show(sysfs->parser, DP_PS5169_EQ1, DP_PS5169_RATE_HBR, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
- return rc;
- }
- static ssize_t dp_ps5169_hbr_eq1_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_64] = {0,};
- int len = min(sizeof(tmp), size);
- if (!len || len >= SZ_64) {
- DP_ERR("wrong length! %d\n", len);
- goto end;
- }
- sysfs = secdp_get_sysfs_private(class);
- memcpy(tmp, buf, len);
- tmp[SZ_64 - 1] = '\0';
- secdp_parse_ps5169_store(sysfs->parser, DP_PS5169_EQ1, DP_PS5169_RATE_HBR, tmp);
- end:
- return size;
- }
- static CLASS_ATTR_RW(dp_ps5169_hbr_eq1);
- static ssize_t dp_ps5169_hbr2_eq0_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_1K] = {0,};
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- secdp_parse_ps5169_show(sysfs->parser, DP_PS5169_EQ0, DP_PS5169_RATE_HBR2, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
- return rc;
- }
- static ssize_t dp_ps5169_hbr2_eq0_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_64] = {0,};
- int len = min(sizeof(tmp), size);
- if (!len || len >= SZ_64) {
- DP_ERR("wrong length! %d\n", len);
- goto end;
- }
- sysfs = secdp_get_sysfs_private(class);
- memcpy(tmp, buf, len);
- tmp[SZ_64 - 1] = '\0';
- secdp_parse_ps5169_store(sysfs->parser, DP_PS5169_EQ0, DP_PS5169_RATE_HBR2, tmp);
- end:
- return size;
- }
- static CLASS_ATTR_RW(dp_ps5169_hbr2_eq0);
- static ssize_t dp_ps5169_hbr2_eq1_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_1K] = {0,};
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- secdp_parse_ps5169_show(sysfs->parser, DP_PS5169_EQ1, DP_PS5169_RATE_HBR2, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
- return rc;
- }
- static ssize_t dp_ps5169_hbr2_eq1_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_64] = {0,};
- int len = min(sizeof(tmp), size);
- if (!len || len >= SZ_64) {
- DP_ERR("wrong length! %d\n", len);
- goto end;
- }
- sysfs = secdp_get_sysfs_private(class);
- memcpy(tmp, buf, len);
- tmp[SZ_64 - 1] = '\0';
- secdp_parse_ps5169_store(sysfs->parser, DP_PS5169_EQ1, DP_PS5169_RATE_HBR2, tmp);
- end:
- return size;
- }
- static CLASS_ATTR_RW(dp_ps5169_hbr2_eq1);
- static ssize_t dp_ps5169_hbr3_eq0_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_1K] = {0,};
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- secdp_parse_ps5169_show(sysfs->parser, DP_PS5169_EQ0, DP_PS5169_RATE_HBR3, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
- return rc;
- }
- static ssize_t dp_ps5169_hbr3_eq0_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_64] = {0,};
- int len = min(sizeof(tmp), size);
- if (!len || len >= SZ_64) {
- DP_ERR("wrong length! %d\n", len);
- goto end;
- }
- sysfs = secdp_get_sysfs_private(class);
- memcpy(tmp, buf, len);
- tmp[SZ_64 - 1] = '\0';
- secdp_parse_ps5169_store(sysfs->parser, DP_PS5169_EQ0, DP_PS5169_RATE_HBR3, tmp);
- end:
- return size;
- }
- static CLASS_ATTR_RW(dp_ps5169_hbr3_eq0);
- static ssize_t dp_ps5169_hbr3_eq1_show(struct class *class,
- struct class_attribute *attr, char *buf)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_1K] = {0,};
- int rc = 0;
- sysfs = secdp_get_sysfs_private(class);
- secdp_parse_ps5169_show(sysfs->parser, DP_PS5169_EQ1, DP_PS5169_RATE_HBR3, tmp);
- rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
- return rc;
- }
- static ssize_t dp_ps5169_hbr3_eq1_store(struct class *class,
- struct class_attribute *attr, const char *buf, size_t size)
- {
- struct secdp_sysfs_private *sysfs;
- char tmp[SZ_64] = {0,};
- int len = min(sizeof(tmp), size);
- if (!len || len >= SZ_64) {
- DP_ERR("wrong length! %d\n", len);
- goto end;
- }
- sysfs = secdp_get_sysfs_private(class);
- memcpy(tmp, buf, len);
- tmp[SZ_64 - 1] = '\0';
- secdp_parse_ps5169_store(sysfs->parser, DP_PS5169_EQ1, DP_PS5169_RATE_HBR3, tmp);
- end:
- return size;
- }
- static CLASS_ATTR_RW(dp_ps5169_hbr3_eq1);
- #endif/*CONFIG_COMBO_REDRIVER_PS5169*/
- #endif/*CONFIG_SECDP_DBG*/
- enum {
- DEX = 0,
- DEX_VER,
- MONITOR_INFO,
- #ifdef SYSFS_BW_CODE
- BW_CODE,
- #endif
- #if defined(CONFIG_SECDP_BIGDATA)
- DP_ERROR_INFO,
- #endif
- #if defined(CONFIG_SECDP_FACTORY_DPSWITCH_TEST)
- DP_SBU_SW_SEL,
- #endif
- #ifdef SECDP_SELF_TEST
- DP_SELF_TEST,
- #endif
- #if defined(CONFIG_SECDP_DBG)
- DP_DBG,
- DP_UNIT_TEST,
- DP_AUX_CFG,
- DP_PRESHOOT,
- DP_HBR2_3_VOLTAGE_SWING,
- DP_HBR2_3_PRE_EMPHASIS,
- DP_HBR_RBR_VOLTAGE_SWING,
- DP_HBR_RBR_PRE_EMPHASIS,
- DP_PREF_SKIP,
- DP_PREF_RATIO,
- #if IS_ENABLED(CONFIG_COMBO_REDRIVER_PS5169)
- DP_PS5169_RBR_EQ0,
- DP_PS5169_RBR_EQ1,
- DP_PS5169_HBR_EQ0,
- DP_PS5169_HBR_EQ1,
- DP_PS5169_HBR2_EQ0,
- DP_PS5169_HBR2_EQ1,
- DP_PS5169_HBR3_EQ0,
- DP_PS5169_HBR3_EQ1,
- #endif/*CONFIG_COMBO_REDRIVER_PS5169*/
- #endif
- };
- static struct attribute *secdp_class_attrs[] = {
- [DEX] = &class_attr_dex.attr,
- [DEX_VER] = &class_attr_dex_ver.attr,
- [MONITOR_INFO] = &class_attr_monitor_info.attr,
- #ifdef SYSFS_BW_CODE
- [BW_CODE] = &class_attr_bw_code.attr,
- #endif
- #if defined(CONFIG_SECDP_BIGDATA)
- [DP_ERROR_INFO] = &class_attr_dp_error_info.attr,
- #endif
- #if defined(CONFIG_SECDP_FACTORY_DPSWITCH_TEST)
- [DP_SBU_SW_SEL] = &class_attr_dp_sbu_sw_sel.attr,
- #endif
- #ifdef SECDP_SELF_TEST
- [DP_SELF_TEST] = &class_attr_dp_self_test.attr,
- #endif
- #if defined(CONFIG_SECDP_DBG)
- [DP_DBG] = &class_attr_dp_debug.attr,
- [DP_UNIT_TEST] = &class_attr_dp_unit_test.attr,
- [DP_AUX_CFG] = &class_attr_dp_aux_cfg.attr,
- [DP_PRESHOOT] = &class_attr_dp_preshoot.attr,
- [DP_HBR_RBR_VOLTAGE_SWING] = &class_attr_dp_hbr_rbr_voltage_swing.attr,
- [DP_HBR_RBR_PRE_EMPHASIS] = &class_attr_dp_hbr_rbr_pre_emphasis.attr,
- [DP_HBR2_3_VOLTAGE_SWING] = &class_attr_dp_hbr2_3_voltage_swing.attr,
- [DP_HBR2_3_PRE_EMPHASIS] = &class_attr_dp_hbr2_3_pre_emphasis.attr,
- [DP_PREF_SKIP] = &class_attr_dp_pref_skip.attr,
- [DP_PREF_RATIO] = &class_attr_dp_pref_ratio.attr,
- #if IS_ENABLED(CONFIG_COMBO_REDRIVER_PS5169)
- [DP_PS5169_RBR_EQ0] = &class_attr_dp_ps5169_rbr_eq0.attr,
- [DP_PS5169_RBR_EQ1] = &class_attr_dp_ps5169_rbr_eq1.attr,
- [DP_PS5169_HBR_EQ0] = &class_attr_dp_ps5169_hbr_eq0.attr,
- [DP_PS5169_HBR_EQ1] = &class_attr_dp_ps5169_hbr_eq1.attr,
- [DP_PS5169_HBR2_EQ0] = &class_attr_dp_ps5169_hbr2_eq0.attr,
- [DP_PS5169_HBR2_EQ1] = &class_attr_dp_ps5169_hbr2_eq1.attr,
- [DP_PS5169_HBR3_EQ0] = &class_attr_dp_ps5169_hbr3_eq0.attr,
- [DP_PS5169_HBR3_EQ1] = &class_attr_dp_ps5169_hbr3_eq1.attr,
- #endif/*CONFIG_COMBO_REDRIVER_PS5169*/
- #endif
- NULL,
- };
- ATTRIBUTE_GROUPS(secdp_class);
- struct secdp_sysfs *secdp_sysfs_get(struct secdp_sysfs_in *in)
- {
- struct class *dp_class = NULL;
- struct secdp_sysfs_private *sysfs = NULL;
- struct secdp_sysfs *dp_sysfs;
- int rc = 0;
- if (!in) {
- DP_ERR("invalid input\n");
- rc = -EINVAL;
- goto error;
- }
- sysfs = devm_kzalloc(in->dev, sizeof(*sysfs), GFP_KERNEL);
- if (!sysfs) {
- rc = -EINVAL;
- DP_ERR("alloc failed %d\n", rc);
- goto error;
- }
- sysfs->dev = in->dev;
- sysfs->parser = in->parser;
- sysfs->power = in->power;
- sysfs->panel = in->panel;
- sysfs->link = in->link;
- sysfs->ctrl = in->ctrl;
- sysfs->catalog = in->catalog;
- sysfs->sec = in->sec;
- dp_sysfs = &sysfs->dp_sysfs;
- dp_class = &dp_sysfs->dp_class;
- dp_class->name = "dp_sec";
- dp_class->owner = THIS_MODULE;
- dp_class->class_groups = secdp_class_groups;
- rc = class_register(dp_class);
- if (rc) {
- DP_ERR("cannot register dp_class %d\n", rc);
- goto free_class;
- }
- #if defined(CONFIG_SECDP_BIGDATA)
- secdp_bigdata_init(dp_class);
- #endif
- #ifdef SECDP_SELF_TEST
- INIT_DELAYED_WORK(&sysfs->sec->self_test_reconnect_work,
- secdp_self_test_reconnect_work);
- INIT_DELAYED_WORK(&sysfs->sec->self_test_hdcp_test_work,
- secdp_self_test_hdcp_test_work);
- #endif
- DP_DEBUG("success\n");
- return dp_sysfs;
- free_class:
- devm_kfree(in->dev, sysfs);
- error:
- return ERR_PTR(rc);
- }
- void secdp_sysfs_put(struct device *dev, struct secdp_sysfs *dp_sysfs)
- {
- struct secdp_sysfs_private *sysfs;
- if (!dp_sysfs)
- return;
- class_unregister(&dp_sysfs->dp_class);
- sysfs = container_of(dp_sysfs, struct secdp_sysfs_private, dp_sysfs);
- devm_kfree(dev, sysfs);
- }
|