| /* |
| * ccic_sysfs.c |
| * |
| * Copyright (C) 2016 Samsung Electronics |
| * |
| * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| * |
| */ |
| |
| #include <linux/types.h> |
| #include <linux/device.h> |
| #include <linux/fs.h> |
| #include <linux/uaccess.h> |
| #include <linux/ccic/ccic_sysfs.h> |
| |
| #ifdef CONFIG_CCIC_S2MM005 |
| #include <linux/ccic/s2mm005.h> |
| #include <linux/ccic/s2mm005_ext.h> |
| #include <linux/ccic/s2mm005_fw.h> |
| #include <linux/regulator/consumer.h> |
| #endif |
| |
| #ifdef CONFIG_CCIC_S2MU004 |
| #include <linux/ccic/usbpd.h> |
| #include <linux/ccic/usbpd-s2mu004.h> |
| #endif |
| |
| #ifdef CONFIG_CCIC_S2MU106 |
| #include <linux/ccic/usbpd.h> |
| #include <linux/ccic/usbpd-s2mu106.h> |
| #endif |
| |
| #ifdef CONFIG_CCIC_S2MU205 |
| #include <linux/ccic/usbpd.h> |
| #include <linux/ccic/usbpd-s2mu205.h> |
| #endif |
| |
| #if defined(CONFIG_CCIC_ALTERNATE_MODE) |
| #include <linux/ccic/ccic_alternate.h> |
| #endif |
| static ssize_t ccic_cur_ver_show(struct device *dev, |
| struct device_attribute *attr, char *buf) |
| { |
| #ifdef CONFIG_CCIC_S2MM005 |
| struct s2mm005_version chip_swver; |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| |
| s2mm005_get_chip_swversion(usbpd_data, &chip_swver); |
| pr_err("%s CHIP SWversion %2x %2x %2x %2x\n", __func__, |
| chip_swver.main[2] , chip_swver.main[1], chip_swver.main[0], chip_swver.boot); |
| |
| usbpd_data->firm_ver[0] = chip_swver.main[2]; |
| usbpd_data->firm_ver[1] = chip_swver.main[1]; |
| usbpd_data->firm_ver[2] = chip_swver.main[0]; |
| usbpd_data->firm_ver[3] = chip_swver.boot; |
| |
| return sprintf(buf, "%02X %02X %02X %02X\n", |
| usbpd_data->firm_ver[0], usbpd_data->firm_ver[1], |
| usbpd_data->firm_ver[2], usbpd_data->firm_ver[3]); |
| #else |
| printk("Need implementation \n"); |
| return 0; |
| |
| #endif |
| |
| } |
| static DEVICE_ATTR(cur_version, 0444, ccic_cur_ver_show, NULL); |
| |
| #ifdef CONFIG_CCIC_S2MU205 |
| static ssize_t ccic_chip_name_show(struct device *dev, |
| struct device_attribute *attr, char *buf) |
| { |
| struct s2mu205_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| |
| if (!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| return sprintf(buf, "%s\n", usbpd_data->name); |
| } |
| static DEVICE_ATTR(chip_name, 0444, ccic_chip_name_show, NULL); |
| #endif |
| |
| static ssize_t ccic_src_ver_show(struct device *dev, |
| struct device_attribute *attr, char *buf) |
| { |
| #ifdef CONFIG_CCIC_S2MM005 |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| struct s2mm005_version fw_swver; |
| |
| s2mm005_get_fw_version(usbpd_data->s2mm005_fw_product_id, |
| &fw_swver, usbpd_data->firm_ver[3], usbpd_data->hw_rev); |
| return sprintf(buf, "%02X %02X %02X %02X\n", |
| fw_swver.main[2], fw_swver.main[1], fw_swver.main[0], fw_swver.boot); |
| #else |
| printk("Need implementation \n"); |
| return 0; |
| |
| #endif |
| |
| } |
| static DEVICE_ATTR(src_version, 0444, ccic_src_ver_show, NULL); |
| |
| static ssize_t ccic_show_manual_lpm_mode(struct device *dev, |
| struct device_attribute *attr, char *buf) |
| { |
| #ifdef CONFIG_CCIC_S2MM005 |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| |
| if (!usbpd_data) { |
| pr_err("usbpd_data is NULL\n"); |
| return -ENODEV; |
| } |
| |
| return sprintf(buf, "%d\n", usbpd_data->manual_lpm_mode); |
| #else |
| #ifdef CONFIG_CCIC_S2MU004 |
| struct s2mu004_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU106 |
| struct s2mu106_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU205 |
| struct s2mu205_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| if (!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| return sprintf(buf, "%d\n", usbpd_data->lpm_mode); |
| #endif |
| |
| |
| } |
| static ssize_t ccic_store_manual_lpm_mode(struct device *dev, |
| struct device_attribute *attr, const char *buf, size_t size) |
| { |
| #ifdef CONFIG_CCIC_S2MM005 |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| int mode; |
| |
| if (!usbpd_data) { |
| pr_err("usbpd_data is NULL\n"); |
| return -ENODEV; |
| } |
| |
| sscanf(buf, "%d", &mode); |
| pr_info("usb: %s mode=%d\n", __func__, mode); |
| |
| switch(mode){ |
| case 0: |
| /* Disable Low Power Mode for App (SW JIGON Disable) */ |
| s2mm005_manual_JIGON(usbpd_data, 0); |
| usbpd_data->manual_lpm_mode = 0; |
| break; |
| case 1: |
| /* Enable Low Power Mode for App (SW JIGON Enable) */ |
| s2mm005_manual_JIGON(usbpd_data, 1); |
| usbpd_data->manual_lpm_mode = 1; |
| break; |
| case 2: |
| /* SW JIGON Enable */ |
| s2mm005_manual_JIGON(usbpd_data, 1); |
| // s2mm005_manual_LPM(usbpd_data, 0x1); |
| usbpd_data->manual_lpm_mode = 1; |
| break; |
| default: |
| /* SW JIGON Disable */ |
| s2mm005_manual_JIGON(usbpd_data, 0); |
| usbpd_data->manual_lpm_mode = 0; |
| break; |
| } |
| |
| return size; |
| #else |
| #ifdef CONFIG_CCIC_S2MU004 |
| struct s2mu004_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU106 |
| struct s2mu106_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU205 |
| struct s2mu205_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| int mode; |
| |
| if (!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| sscanf(buf, "%d", &mode); |
| pr_info("usb: %s mode=%d\n", __func__, mode); |
| |
| mutex_lock(&usbpd_data->lpm_mutex); |
| |
| #ifdef CONFIG_SEC_FACTORY |
| if (mode != 1 && mode != 2) { |
| #ifdef CONFIG_CCIC_S2MU004 |
| s2mu004_set_normal_mode(usbpd_data); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU106 |
| s2mu106_set_normal_mode(usbpd_data); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU205 |
| s2mu205_set_normal_mode(usbpd_data); |
| #endif |
| } |
| #else |
| if (mode == 1 || mode == 2) { |
| #ifdef CONFIG_CCIC_S2MU004 |
| s2mu004_set_lpm_mode(usbpd_data); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU106 |
| s2mu106_set_lpm_mode(usbpd_data); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU205 |
| s2mu205_set_lpm_mode(usbpd_data); |
| #endif |
| } |
| else { |
| #ifdef CONFIG_CCIC_S2MU004 |
| s2mu004_set_normal_mode(usbpd_data); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU106 |
| s2mu106_set_normal_mode(usbpd_data); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU205 |
| s2mu205_set_normal_mode(usbpd_data); |
| #endif |
| } |
| #endif |
| |
| mutex_unlock(&usbpd_data->lpm_mutex); |
| |
| return size; |
| #endif |
| |
| } |
| |
| static DEVICE_ATTR(lpm_mode, 0664, |
| ccic_show_manual_lpm_mode, ccic_store_manual_lpm_mode); |
| |
| static ssize_t ccic_state_show(struct device *dev, |
| struct device_attribute *attr, char *buf) |
| { |
| #ifdef CONFIG_CCIC_S2MM005 |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| |
| if (!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| return sprintf(buf, "%d\n", usbpd_data->pd_state); |
| #else |
| #ifdef CONFIG_CCIC_S2MU004 |
| struct s2mu004_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU106 |
| struct s2mu106_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU205 |
| struct s2mu205_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| |
| if (!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } else { |
| struct usbpd_data *pd_data = dev_get_drvdata(usbpd_data->dev); |
| |
| if (!pd_data) { |
| pr_err("%s pd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| return sprintf(buf, "%d\n", pd_data->policy.plug_valid); |
| } |
| #endif |
| } |
| static DEVICE_ATTR(state, 0444, ccic_state_show, NULL); |
| |
| #if defined(CONFIG_SEC_FACTORY) |
| static ssize_t ccic_rid_show(struct device *dev, |
| struct device_attribute *attr, char *buf) |
| { |
| |
| #ifdef CONFIG_CCIC_S2MM005 |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| |
| if (!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| return sprintf(buf, "%d\n", usbpd_data->cur_rid); |
| #else |
| #ifdef CONFIG_CCIC_S2MU004 |
| struct s2mu004_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU106 |
| struct s2mu106_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU205 |
| struct s2mu205_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| |
| if (!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| return sprintf(buf, "%d\n", usbpd_data->rid == REG_RID_MAX ? REG_RID_OPEN : usbpd_data->rid); |
| |
| #endif |
| |
| } |
| static DEVICE_ATTR(rid, 0444, ccic_rid_show, NULL); |
| |
| static ssize_t ccic_store_control_option_command(struct device *dev, |
| struct device_attribute *attr, const char *buf, size_t size) |
| { |
| #ifdef CONFIG_CCIC_S2MM005 |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| int cmd; |
| |
| if (!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| sscanf(buf, "%d", &cmd); |
| pr_info("usb: %s mode=%d\n", __func__, cmd); |
| |
| s2mm005_control_option_command(usbpd_data, cmd); |
| |
| return size; |
| #else |
| #ifdef CONFIG_CCIC_S2MU004 |
| struct s2mu004_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU106 |
| struct s2mu106_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU205 |
| struct s2mu205_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| int cmd; |
| |
| if (!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| sscanf(buf, "%d", &cmd); |
| pr_info("usb: %s mode=%d\n", __func__, cmd); |
| |
| #ifdef CONFIG_CCIC_S2MU004 |
| s2mu004_control_option_command(usbpd_data, cmd); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU106 |
| s2mu106_control_option_command(usbpd_data, cmd); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU205 |
| s2mu205_control_option_command(usbpd_data, cmd); |
| #endif |
| return size; |
| |
| #endif |
| |
| |
| } |
| static DEVICE_ATTR(ccic_control_option, 0220, NULL, ccic_store_control_option_command); |
| |
| static ssize_t ccic_booting_dry_show(struct device *dev, |
| struct device_attribute *attr, char *buf) |
| { |
| #ifdef CONFIG_CCIC_S2MM005 |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| |
| if(!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| pr_info("%s booting_run_dry=%d\n", __func__, |
| usbpd_data->fac_booting_dry_check); |
| |
| return sprintf(buf, "%d\n", (usbpd_data->fac_booting_dry_check)); |
| #else |
| pr_info("%s booting_run_dry is not supported \n", __func__); |
| return 0; |
| #endif |
| } |
| static DEVICE_ATTR(booting_dry, 0444, ccic_booting_dry_show, NULL); |
| #endif |
| |
| #ifdef CONFIG_CCIC_S2MM005 |
| static int ccic_firmware_update_built_in(struct device *dev) |
| { |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| struct s2mm005_version chip_swver, fw_swver; |
| |
| s2mm005_get_chip_swversion(usbpd_data, &chip_swver); |
| pr_err("%s CHIP SWversion %2x %2x %2x %2x - before\n", __func__, |
| chip_swver.main[2] , chip_swver.main[1], chip_swver.main[0], chip_swver.boot); |
| s2mm005_get_fw_version(usbpd_data->s2mm005_fw_product_id, |
| &fw_swver, chip_swver.boot, usbpd_data->hw_rev); |
| pr_err("%s SRC SWversion:%2x,%2x,%2x,%2x\n",__func__, |
| fw_swver.main[2], fw_swver.main[1], fw_swver.main[0], fw_swver.boot); |
| |
| pr_err("%s: FW UPDATE boot:%01d hw_rev:%02d\n", __func__, chip_swver.boot, usbpd_data->hw_rev); |
| |
| if(chip_swver.main[0] == fw_swver.main[0]) { |
| pr_err("%s: FW version is same. Stop FW update. src:%2x chip:%2x\n", |
| __func__, chip_swver.main[0], fw_swver.main[0]); |
| goto done; |
| } |
| |
| s2mm005_flash_fw(usbpd_data, chip_swver.boot); |
| |
| done: |
| return 0; |
| } |
| |
| static int ccic_firmware_update_ums(struct device *dev) |
| { |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| unsigned char *fw_data; |
| struct s2mm005_fw *fw_hd; |
| struct file *fp; |
| mm_segment_t old_fs; |
| long fw_size, nread; |
| int error = 0; |
| |
| if (!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| old_fs = get_fs(); |
| set_fs(KERNEL_DS); |
| |
| fp = filp_open(CCIC_DEFAULT_UMS_FW, O_RDONLY, S_IRUSR); |
| if (IS_ERR(fp)) { |
| pr_err("%s: failed to open %s.\n", __func__, |
| CCIC_DEFAULT_UMS_FW); |
| error = -ENOENT; |
| goto open_err; |
| } |
| |
| fw_size = fp->f_path.dentry->d_inode->i_size; |
| |
| if (0 < fw_size) { |
| fw_data = kzalloc(fw_size, GFP_KERNEL); |
| nread = vfs_read(fp, (char __user *)fw_data, fw_size, &fp->f_pos); |
| |
| pr_info("%s: start, file path %s, size %ld Bytes\n", |
| __func__, CCIC_DEFAULT_UMS_FW, fw_size); |
| filp_close(fp, NULL); |
| |
| if (nread != fw_size) { |
| pr_err("%s: failed to read firmware file, nread %ld Bytes\n", |
| __func__, nread); |
| error = -EIO; |
| } else { |
| fw_hd = (struct s2mm005_fw *)fw_data; |
| pr_info("CCIC FW ver - cur:%02X %02X %02X %02X / bin:%02X %02X %02X %02X\n", |
| usbpd_data->firm_ver[0], usbpd_data->firm_ver[1], usbpd_data->firm_ver[2], usbpd_data->firm_ver[3], |
| fw_hd->boot, fw_hd->main[0], fw_hd->main[1], fw_hd->main[2]); |
| |
| if (fw_hd->boot == usbpd_data->firm_ver[3]) { |
| if (s2mm005_flash_fw(usbpd_data, FLASH_WRITE_UMS) >= 0) |
| goto done; |
| } else { |
| pr_err("error : Didn't match to CCIC FW firmware version\n"); |
| error = -EINVAL; |
| } |
| } |
| if (error < 0) |
| pr_err("%s: failed update firmware\n", __func__); |
| done: |
| kfree(fw_data); |
| } |
| |
| open_err: |
| set_fs(old_fs); |
| return error; |
| } |
| |
| static ssize_t ccic_store_firmware_status_show(struct device *dev, |
| struct device_attribute *attr, char *buf) |
| { |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| u8 val = 0; |
| |
| if (!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| s2mm005_read_byte_flash(usbpd_data->i2c, FLASH_STATUS_0x24, &val, 1); |
| pr_err("%s flash mode: %s\n", __func__, flashmode_to_string(val)); |
| |
| return sprintf(buf, "%s\n", flashmode_to_string(val)); |
| } |
| static DEVICE_ATTR(fw_update_status, 0444, ccic_store_firmware_status_show, NULL); |
| |
| static ssize_t ccic_store_firmware_update(struct device *dev, |
| struct device_attribute *attr, const char *buf, size_t size) |
| { |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| struct s2mm005_version version; |
| int mode = 0, ret = 1; |
| |
| if (!usbpd_data) { |
| pr_err("usbpd_data is NULL\n"); |
| return -ENODEV; |
| } |
| |
| sscanf(buf, "%d", &mode); |
| pr_info("%s mode=%d\n", __func__, mode); |
| |
| s2mm005_get_chip_swversion(usbpd_data, &version); |
| pr_err("%s CHIP SWversion %2x %2x %2x %2x - before\n", __func__, |
| version.main[2] , version.main[1], version.main[0], version.boot); |
| |
| /* Factory cmd for firmware update |
| * argument represent what is source of firmware like below. |
| * 0 : [BUILT_IN] Getting firmware from source. |
| * 1 : [UMS] Getting firmware from sd card. |
| */ |
| |
| switch (mode) { |
| case BUILT_IN: |
| ret = ccic_firmware_update_built_in(dev); |
| break; |
| case UMS: |
| ret = ccic_firmware_update_ums(dev); |
| break; |
| default: |
| pr_err("%s: Not support command[%d]\n", |
| __func__, mode); |
| break; |
| } |
| |
| s2mm005_get_chip_swversion(usbpd_data, &version); |
| pr_err("%s CHIP SWversion %2x %2x %2x %2x - after\n", __func__, |
| version.main[2] , version.main[1], version.main[0], version.boot); |
| |
| return size; |
| } |
| static DEVICE_ATTR(fw_update, 0220, NULL, ccic_store_firmware_update); |
| |
| static ssize_t ccic_store_sink_pdo_update(struct device *dev, |
| struct device_attribute *attr, const char *buf, size_t size) |
| { |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| uint32_t data = 0; |
| uint16_t REG_ADD; |
| uint8_t MSG_BUF[32] = {0,}; |
| SINK_VAR_SUPPLY_Typedef *pSINK_MSG; |
| MSG_HEADER_Typedef *pMSG_HEADER; |
| uint32_t * MSG_DATA; |
| uint8_t cnt; |
| |
| if (!usbpd_data) { |
| pr_err("usbpd_data is NULL\n"); |
| return -ENODEV; |
| } |
| |
| sscanf(buf, "%x\n", &data); |
| if (data == 0) |
| data = 0x8F019032; // 5V~12V, 500mA |
| pr_info("%s data=0x%x\n", __func__, data); |
| |
| /* update Sink PDO */ |
| REG_ADD = REG_TX_SINK_CAPA_MSG; |
| s2mm005_read_byte(usbpd_data->i2c, REG_ADD, MSG_BUF, 32); |
| |
| MSG_DATA = (uint32_t *)&MSG_BUF[0]; |
| pr_err("--- Read Data on TX_SNK_CAPA_MSG(0x220)\n"); |
| for(cnt = 0; cnt < 8; cnt++) { |
| pr_err(" 0x%08X\n", MSG_DATA[cnt]); |
| } |
| |
| pMSG_HEADER = (MSG_HEADER_Typedef *)&MSG_BUF[0]; |
| pMSG_HEADER->BITS.Number_of_obj += 1; |
| pSINK_MSG = (SINK_VAR_SUPPLY_Typedef *)&MSG_BUF[8]; |
| pSINK_MSG->DATA = data; |
| pr_err("--- Write DATA\n"); |
| for (cnt = 0; cnt < 8; cnt++) { |
| pr_err(" 0x%08X\n", MSG_DATA[cnt]); |
| } |
| |
| s2mm005_write_byte(usbpd_data->i2c, REG_ADD, &MSG_BUF[0], 32); |
| |
| for (cnt = 0; cnt < 32; cnt++) { |
| MSG_BUF[cnt] = 0; |
| } |
| |
| for (cnt = 0; cnt < 8; cnt++) { |
| pr_err(" 0x%08X\n", MSG_DATA[cnt]); |
| } |
| s2mm005_read_byte(usbpd_data->i2c, REG_ADD, MSG_BUF, 32); |
| |
| pr_err("--- Read 2 new Data on TX_SNK_CAPA_MSG(0x220)\n"); |
| for(cnt = 0; cnt < 8; cnt++) { |
| pr_err(" 0x%08X\n", MSG_DATA[cnt]); |
| } |
| |
| return size; |
| } |
| static DEVICE_ATTR(sink_pdo_update, 0220, NULL, ccic_store_sink_pdo_update); |
| #endif |
| |
| #if defined(CONFIG_CCIC_ALTERNATE_MODE) |
| static ssize_t ccic_send_samsung_uVDM_message(struct device *dev, |
| struct device_attribute *attr, const char *buf, size_t size) |
| { |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| int ret = 0; |
| |
| if (!usbpd_data) { |
| pr_err("usbpd_data is NULL\n"); |
| return -ENODEV; |
| } |
| ret = send_samsung_unstructured_vdm_message(usbpd_data, buf, size); |
| if( ret < 0 ) |
| return ret; |
| else |
| return size; |
| } |
| static DEVICE_ATTR(samsung_uvdm, 0220, NULL, ccic_send_samsung_uVDM_message); |
| |
| static ssize_t ccic_send_uVDM_message(struct device *dev, |
| struct device_attribute *attr, const char *buf, size_t size) |
| { |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| int cmd = 0; |
| |
| if (!usbpd_data) { |
| pr_err("usbpd_data is NULL\n"); |
| return -ENODEV; |
| } |
| |
| sscanf(buf, "%d", &cmd); |
| pr_info("%s cmd=%d\n", __func__, cmd); |
| |
| send_unstructured_vdm_message(usbpd_data, cmd); |
| |
| return size; |
| } |
| static DEVICE_ATTR(uvdm, 0220, NULL, ccic_send_uVDM_message); |
| |
| static ssize_t ccic_send_dna_audio_uVDM_message(struct device *dev, |
| struct device_attribute *attr, const char *buf, size_t size) |
| { |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| int cmd = 0; |
| |
| if (!usbpd_data) { |
| pr_err("usbpd_data is NULL\n"); |
| return -ENODEV; |
| } |
| |
| sscanf(buf, "%d", &cmd); |
| pr_info("%s cmd=%d\n", __func__, cmd); |
| |
| send_dna_audio_unstructured_vdm_message(usbpd_data, cmd); |
| |
| return size; |
| } |
| static DEVICE_ATTR(dna_audio_uvdm, 0220, NULL, ccic_send_dna_audio_uVDM_message); |
| |
| static ssize_t ccic_send_dex_fan_uVDM_message(struct device *dev, |
| struct device_attribute *attr, const char *buf, size_t size) |
| { |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| int cmd = 0; |
| |
| if (!usbpd_data) { |
| pr_err("usbpd_data is NULL\n"); |
| return -ENODEV; |
| } |
| |
| sscanf(buf, "%d", &cmd); |
| pr_info("%s cmd=%d\n", __func__, cmd); |
| |
| send_dex_fan_unstructured_vdm_message(usbpd_data, cmd); |
| |
| return size; |
| } |
| static DEVICE_ATTR(dex_fan_uvdm, 0220, NULL, ccic_send_dex_fan_uVDM_message); |
| |
| static ssize_t ccic_send_attention_message(struct device *dev, |
| struct device_attribute *attr, const char *buf, size_t size) |
| { |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| int cmd = 0; |
| |
| if (!usbpd_data) { |
| pr_err("usbpd_data is NULL\n"); |
| return -ENODEV; |
| } |
| |
| sscanf(buf, "%d", &cmd); |
| pr_info("%s cmd=%d\n", __func__, cmd); |
| |
| send_attention_message(usbpd_data, cmd); |
| |
| return size; |
| } |
| static DEVICE_ATTR(attention, 0220, NULL, ccic_send_attention_message); |
| |
| static ssize_t ccic_send_role_swap_message(struct device *dev, |
| struct device_attribute *attr, const char *buf, size_t size) |
| { |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| int cmd = 0; |
| |
| if (!usbpd_data) { |
| pr_err("usbpd_data is NULL\n"); |
| return -ENODEV; |
| } |
| |
| sscanf(buf, "%d", &cmd); |
| pr_info("%s cmd=%d\n", __func__, cmd); |
| |
| send_role_swap_message(usbpd_data, cmd); |
| |
| return size; |
| } |
| static DEVICE_ATTR(role_swap, 0220, NULL, ccic_send_role_swap_message); |
| #endif |
| |
| static ssize_t ccic_acc_device_version_show(struct device *dev, |
| struct device_attribute *attr, char *buf) |
| { |
| #ifdef CONFIG_CCIC_S2MM005 |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| |
| if (!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| pr_info("%s 0x%04x\n", __func__, usbpd_data->Device_Version); |
| |
| return sprintf(buf, "%04x\n", usbpd_data->Device_Version); |
| #else |
| #ifdef CONFIG_CCIC_S2MU004 |
| struct s2mu004_usbpd_data *pdic_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU106 |
| struct s2mu106_usbpd_data *pdic_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU205 |
| struct s2mu205_usbpd_data *pdic_data = dev_get_drvdata(dev); |
| #endif |
| struct usbpd_data *pd_data; |
| struct usbpd_manager_data *manager; |
| |
| if (!pdic_data) { |
| pr_err("%s data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| pd_data = dev_get_drvdata(pdic_data->dev); |
| if (!pd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| manager = &pd_data->manager; |
| if (!manager) { |
| pr_err("%s manager_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| pr_info("%s 0x%04x\n", __func__, manager->Device_Version); |
| |
| return sprintf(buf, "%04x\n", manager->Device_Version); |
| #endif |
| } |
| static DEVICE_ATTR(acc_device_version, 0444, ccic_acc_device_version_show,NULL); |
| |
| #ifdef CONFIG_CCIC_S2MM005 |
| static ssize_t ccic_set_gpio(struct device *dev, |
| struct device_attribute *attr, const char *buf, size_t size) |
| { |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| int mode; |
| u8 W_DATA[2]; |
| u8 REG_ADD; |
| u8 R_DATA; |
| int i; |
| struct device_node *np = NULL; |
| const char *ss_vdd; |
| int ret = 0; |
| struct regulator *vdd085_usb; |
| |
| if (!usbpd_data) { |
| pr_err("usbpd_data is NULL\n"); |
| return -ENODEV; |
| } |
| |
| sscanf(buf, "%d", &mode); |
| pr_info("usb: %s mode=%d\n", __func__, mode); |
| |
| /* VDD_USB_3P0_AP is on for DP SWITCH */ |
| np = of_find_compatible_node(NULL, NULL, "samsung,usb-notifier"); |
| if (!np) { |
| pr_err("%s: failed to get the battery device node\n", __func__); |
| return 0; |
| } else { |
| if(of_property_read_string(np, "hs-regulator", (char const **)&ss_vdd) < 0) { |
| pr_err("%s - get ss_vdd error\n", __func__); |
| } |
| |
| vdd085_usb = regulator_get(NULL, ss_vdd); |
| if (IS_ERR(vdd085_usb) || vdd085_usb == NULL) { |
| pr_err("%s - vdd085_usb regulator_get fail\n", __func__); |
| return 0; |
| } |
| |
| } |
| /* for Wake up*/ |
| for(i=0; i<5; i++){ |
| R_DATA = 0x00; |
| REG_ADD = 0x8; |
| s2mm005_read_byte(usbpd_data->i2c, REG_ADD, &R_DATA, 1); //dummy read |
| } |
| udelay(10); |
| |
| switch(mode){ |
| case 0: |
| if (!regulator_is_enabled(vdd085_usb)) { |
| ret = regulator_enable(vdd085_usb); |
| if (ret) { |
| pr_err("%s - enable vdd085_usb ldo enable failed, ret=%d\n", |
| __func__, ret); |
| regulator_put(vdd085_usb); |
| return 0; |
| } |
| } |
| regulator_put(vdd085_usb); |
| |
| /* SBU1/SBU2 set as open-drain status*/ |
| // SBU1/2 Open command ON |
| REG_ADD = 0x10; |
| W_DATA[0] = 0x03; |
| W_DATA[1] = 0x85; |
| s2mm005_write_byte(usbpd_data->i2c, REG_ADD, &W_DATA[0], 2); |
| |
| break; |
| case 1: |
| /* SBU1/SBU2 set as default status */ |
| // SBU1/2 Open command OFF |
| REG_ADD = 0x10; |
| W_DATA[0] = 0x03; |
| W_DATA[1] = 0x86; |
| s2mm005_write_byte(usbpd_data->i2c, REG_ADD, &W_DATA[0], 2); |
| |
| if (regulator_is_enabled(vdd085_usb)) { |
| ret = regulator_disable(vdd085_usb); |
| if (ret) { |
| pr_err("%s - enable vdd085_usb ldo enable failed, ret=%d\n", |
| __func__, ret); |
| regulator_put(vdd085_usb); |
| return 0; |
| } |
| } |
| regulator_put(vdd085_usb); |
| break; |
| default: |
| break; |
| } |
| |
| return size; |
| } |
| |
| static ssize_t ccic_get_gpio(struct device *dev, |
| struct device_attribute *attr, char *buf) |
| { |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| u8 W_DATA[4]; |
| u8 REG_ADD; |
| u8 R_DATA; |
| int i; |
| |
| if (!usbpd_data) { |
| pr_err("usbpd_data is NULL\n"); |
| return -ENODEV; |
| } |
| |
| /* for Wake up*/ |
| for(i=0; i<5; i++){ |
| R_DATA = 0x00; |
| REG_ADD = 0x8; |
| s2mm005_read_byte(usbpd_data->i2c, REG_ADD, &R_DATA, 1); //dummy read |
| } |
| udelay(10); |
| |
| W_DATA[0] =0x2; |
| W_DATA[1] =0x10; |
| |
| W_DATA[2] =0x84; |
| W_DATA[3] =0x10; |
| |
| s2mm005_write_byte(usbpd_data->i2c, 0x10, &W_DATA[0], 4); |
| s2mm005_read_byte(usbpd_data->i2c, 0x14, &R_DATA, 1); |
| |
| pr_err("%s SBU1 status = %2x , SBU2 status = %2x \n", __func__, |
| (R_DATA & 0x10) >> 4,(R_DATA & 0x20) >> 5); |
| |
| return sprintf(buf, "%d %d\n", (R_DATA & 0x10) >> 4,(R_DATA & 0x20) >> 5); |
| |
| } |
| static DEVICE_ATTR(control_gpio, 0664, ccic_get_gpio, ccic_set_gpio); |
| #endif |
| |
| #if defined(CONFIG_SEC_FACTORY) |
| #if defined(CONFIG_CCIC_S2MU106) || defined(CONFIG_CCIC_S2MU205) |
| static ssize_t ccic_power_off_water_check_show(struct device *dev, |
| struct device_attribute *attr, char *buf) |
| { |
| #if defined(CONFIG_CCIC_S2MU106) |
| struct s2mu106_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #elif defined(CONFIG_CCIC_S2MU205) |
| struct s2mu205_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| int ret = 0; |
| |
| if (!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| #if defined(CONFIG_CCIC_S2MU106) |
| ret = s2mu106_sys_power_off_water_check(usbpd_data); |
| #elif defined(CONFIG_CCIC_S2MU205) |
| ret = s2mu205_power_off_water_check(usbpd_data); |
| #endif |
| |
| return sprintf(buf, "%d\n", ret); |
| } |
| |
| static DEVICE_ATTR(water_check, 0444, ccic_power_off_water_check_show, NULL); |
| #endif |
| #endif /* CONFIG_SEC_FACTORY */ |
| |
| static ssize_t ccic_usbpd_ids_show(struct device *dev, |
| struct device_attribute *attr, char *buf) |
| { |
| #ifdef CONFIG_CCIC_S2MM005 |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| int retval = 0; |
| |
| if (!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| retval = sprintf(buf, "%04x:%04x\n", |
| le16_to_cpu(usbpd_data->Vendor_ID), |
| le16_to_cpu(usbpd_data->Product_ID)); |
| pr_info("usb: %s : %s", |
| __func__, buf); |
| #else |
| #ifdef CONFIG_CCIC_S2MU004 |
| struct s2mu004_usbpd_data *pdic_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU106 |
| struct s2mu106_usbpd_data *pdic_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU205 |
| struct s2mu205_usbpd_data *pdic_data = dev_get_drvdata(dev); |
| #endif |
| struct usbpd_data *pd_data; |
| struct usbpd_manager_data *manager; |
| int retval = 0; |
| |
| if (!pdic_data) { |
| pr_err("%s data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| pd_data = dev_get_drvdata(pdic_data->dev); |
| if (!pd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| manager = &pd_data->manager; |
| if (!manager) { |
| pr_err("%s manager_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| retval = sprintf(buf, "%04x:%04x\n", |
| le16_to_cpu(manager->Vendor_ID), |
| le16_to_cpu(manager->Product_ID)); |
| pr_info("usb: %s : %s", |
| __func__, buf); |
| #endif |
| return retval; |
| } |
| static DEVICE_ATTR(usbpd_ids, 0444, ccic_usbpd_ids_show, NULL); |
| |
| static ssize_t ccic_usbpd_type_show(struct device *dev, |
| struct device_attribute *attr, char *buf) |
| { |
| #ifdef CONFIG_CCIC_S2MM005 |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| int retval = 0; |
| |
| if (!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| retval = sprintf(buf, "%d\n", usbpd_data->acc_type); |
| pr_info("usb: %s : %d", |
| __func__, usbpd_data->acc_type); |
| #else |
| #ifdef CONFIG_CCIC_S2MU004 |
| struct s2mu004_usbpd_data *pdic_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU106 |
| struct s2mu106_usbpd_data *pdic_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU205 |
| struct s2mu205_usbpd_data *pdic_data = dev_get_drvdata(dev); |
| #endif |
| struct usbpd_data *pd_data; |
| struct usbpd_manager_data *manager; |
| int retval = 0; |
| |
| if (!pdic_data) { |
| pr_err("%s data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| pd_data = dev_get_drvdata(pdic_data->dev); |
| if (!pd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| |
| manager = &pd_data->manager; |
| if (!manager) { |
| pr_err("%s manager_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| retval = sprintf(buf, "%d\n", manager->acc_type); |
| pr_info("usb: %s : %d", |
| __func__, manager->acc_type); |
| #endif |
| return retval; |
| } |
| static DEVICE_ATTR(usbpd_type, 0444, ccic_usbpd_type_show, NULL); |
| |
| static ssize_t ccic_water_show(struct device *dev, |
| struct device_attribute *attr, char *buf) |
| { |
| #ifdef CONFIG_CCIC_S2MM005 |
| struct s2mm005_data *usbpd_data = dev_get_drvdata(dev); |
| |
| if(!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| pr_info("%s water=%d, run_dry=%d\n", __func__, |
| usbpd_data->water_det, usbpd_data->run_dry); |
| |
| return sprintf(buf, "%d\n", (usbpd_data->water_det | !usbpd_data->run_dry)); |
| #else |
| #ifdef CONFIG_CCIC_S2MU004 |
| struct s2mu004_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU106 |
| struct s2mu106_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| #ifdef CONFIG_CCIC_S2MU205 |
| struct s2mu205_usbpd_data *usbpd_data = dev_get_drvdata(dev); |
| #endif |
| |
| if(!usbpd_data) { |
| pr_err("%s usbpd_data is null!!\n", __func__); |
| return -ENODEV; |
| } |
| pr_info("%s is_water_detect=%d\n", __func__, |
| (int)usbpd_data->is_water_detect); |
| |
| return sprintf(buf, "%d\n", usbpd_data->is_water_detect); |
| #endif |
| } |
| static DEVICE_ATTR(water, 0444, ccic_water_show, NULL); |
| |
| static struct attribute *ccic_attributes[] = { |
| &dev_attr_cur_version.attr, |
| &dev_attr_src_version.attr, |
| &dev_attr_lpm_mode.attr, |
| &dev_attr_state.attr, |
| #if defined(CONFIG_SEC_FACTORY) |
| &dev_attr_rid.attr, |
| &dev_attr_ccic_control_option.attr, |
| &dev_attr_booting_dry.attr, |
| #endif |
| #if (defined(CONFIG_CCIC_S2MU106) || defined(CONFIG_CCIC_S2MU205)) && defined(CONFIG_SEC_FACTORY) |
| &dev_attr_water_check.attr, |
| #endif |
| #ifdef CONFIG_CCIC_S2MM005 |
| &dev_attr_fw_update.attr, |
| &dev_attr_fw_update_status.attr, |
| &dev_attr_sink_pdo_update.attr, |
| #endif |
| #if defined(CONFIG_CCIC_ALTERNATE_MODE) |
| &dev_attr_uvdm.attr, |
| &dev_attr_attention.attr, |
| &dev_attr_role_swap.attr, |
| &dev_attr_samsung_uvdm.attr, |
| &dev_attr_dna_audio_uvdm.attr, |
| &dev_attr_dex_fan_uvdm.attr, |
| #endif |
| &dev_attr_acc_device_version.attr, |
| &dev_attr_usbpd_ids.attr, |
| &dev_attr_usbpd_type.attr, |
| #ifdef CONFIG_CCIC_S2MM005 |
| &dev_attr_control_gpio.attr, |
| #endif |
| &dev_attr_water.attr, |
| #ifdef CONFIG_CCIC_S2MU205 |
| &dev_attr_chip_name.attr, |
| #endif |
| NULL |
| }; |
| |
| const struct attribute_group ccic_sysfs_group = { |
| .attrs = ccic_attributes, |
| }; |
| |