^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is provided under a GPLv2 license. When using or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * redistributing this file, you may do so under that license.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * GPL LICENSE SUMMARY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2016 T-Platforms. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This program is free software; you can redistribute it and/or modify it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * under the terms and conditions of the GNU General Public License,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * version 2, as published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * This program is distributed in the hope that it will be useful, but WITHOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * You should have received a copy of the GNU General Public License along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * with this program; if not, it can be found <http://www.gnu.org/licenses/>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * The full GNU General Public License is included in this distribution in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * the file called "COPYING".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * IDT PCIe-switch NTB Linux driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * Contact Information:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * Serge Semin <fancer.lancer@gmail.com>, <Sergey.Semin@t-platforms.ru>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * NOTE of the IDT 89HPESx SMBus-slave interface driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * This driver primarily is developed to have an access to EEPROM device of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * IDT PCIe-switches. IDT provides a simple SMBus interface to perform IO-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * operations from/to EEPROM, which is located at private (so called Master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * SMBus of switches. Using that interface this the driver creates a simple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * binary sysfs-file in the device directory:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * /sys/bus/i2c/devices/<bus>-<devaddr>/eeprom
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * In case if read-only flag is specified in the dts-node of device desription,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * User-space applications won't be able to write to the EEPROM sysfs-node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Additionally IDT 89HPESx SMBus interface has an ability to write/read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * data of device CSRs. This driver exposes debugf-file to perform simple IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * operations using that ability for just basic debug purpose. Particularly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * next file is created in the specific debugfs-directory:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * /sys/kernel/debug/idt_csr/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * Format of the debugfs-node is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * $ cat /sys/kernel/debug/idt_csr/<bus>-<devaddr>/<devname>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * <CSR address>:<CSR value>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * So reading the content of the file gives current CSR address and it value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * If User-space application wishes to change current CSR address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * it can just write a proper value to the sysfs-file:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * $ echo "<CSR address>" > /sys/kernel/debug/idt_csr/<bus>-<devaddr>/<devname>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * If it wants to change the CSR value as well, the format of the write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * operation is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * $ echo "<CSR address>:<CSR value>" > \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * /sys/kernel/debug/idt_csr/<bus>-<devaddr>/<devname>;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * CSR address and value can be any of hexadecimal, decimal or octal format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #include <linux/sizes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #include <linux/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #include <linux/mod_devicetable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #include <linux/property.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #include <linux/pci_ids.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define IDT_NAME "89hpesx"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define IDT_89HPESX_DESC "IDT 89HPESx SMBus-slave interface driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define IDT_89HPESX_VER "1.0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) MODULE_DESCRIPTION(IDT_89HPESX_DESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) MODULE_VERSION(IDT_89HPESX_VER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) MODULE_AUTHOR("T-platforms");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * csr_dbgdir - CSR read/write operations Debugfs directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static struct dentry *csr_dbgdir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * struct idt_89hpesx_dev - IDT 89HPESx device data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * @eesize: Size of EEPROM in bytes (calculated from "idt,eecompatible")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * @eero: EEPROM Read-only flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * @eeaddr: EEPROM custom address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * @inieecmd: Initial cmd value for EEPROM read/write operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * @inicsrcmd: Initial cmd value for CSR read/write operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * @iniccode: Initialial command code value for IO-operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * @csr: CSR address to perform read operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * @smb_write: SMBus write method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * @smb_read: SMBus read method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * @smb_mtx: SMBus mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * @client: i2c client used to perform IO operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * @ee_file: EEPROM read/write sysfs-file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct idt_smb_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct idt_89hpesx_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) u32 eesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) bool eero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u8 eeaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) u8 inieecmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u8 inicsrcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) u8 iniccode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) u16 csr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) int (*smb_write)(struct idt_89hpesx_dev *, const struct idt_smb_seq *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) int (*smb_read)(struct idt_89hpesx_dev *, struct idt_smb_seq *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct mutex smb_mtx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct bin_attribute *ee_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct dentry *csr_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * struct idt_smb_seq - sequence of data to be read/written from/to IDT 89HPESx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * @ccode: SMBus command code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * @bytecnt: Byte count of operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * @data: Data to by written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct idt_smb_seq {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) u8 ccode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) u8 bytecnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) u8 *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * struct idt_eeprom_seq - sequence of data to be read/written from/to EEPROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * @cmd: Transaction CMD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * @eeaddr: EEPROM custom address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * @memaddr: Internal memory address of EEPROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * @data: Data to be written at the memory address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct idt_eeprom_seq {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) u8 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) u8 eeaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u16 memaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u8 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * struct idt_csr_seq - sequence of data to be read/written from/to CSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * @cmd: Transaction CMD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * @csraddr: Internal IDT device CSR address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * @data: Data to be read/written from/to the CSR address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct idt_csr_seq {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u8 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u16 csraddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * SMBus command code macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * @CCODE_END: Indicates the end of transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * @CCODE_START: Indicates the start of transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * @CCODE_CSR: CSR read/write transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * @CCODE_EEPROM: EEPROM read/write transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * @CCODE_BYTE: Supplied data has BYTE length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * @CCODE_WORD: Supplied data has WORD length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * @CCODE_BLOCK: Supplied data has variable length passed in bytecnt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * byte right following CCODE byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define CCODE_END ((u8)0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define CCODE_START ((u8)0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define CCODE_CSR ((u8)0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define CCODE_EEPROM ((u8)0x04)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define CCODE_BYTE ((u8)0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define CCODE_WORD ((u8)0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define CCODE_BLOCK ((u8)0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define CCODE_PEC ((u8)0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * EEPROM command macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * @EEPROM_OP_WRITE: EEPROM write operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * @EEPROM_OP_READ: EEPROM read operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * @EEPROM_USA: Use specified address of EEPROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * @EEPROM_NAERR: EEPROM device is not ready to respond
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * @EEPROM_LAERR: EEPROM arbitration loss error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * @EEPROM_MSS: EEPROM misplace start & stop bits error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * @EEPROM_WR_CNT: Bytes count to perform write operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * @EEPROM_WRRD_CNT: Bytes count to write before reading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * @EEPROM_RD_CNT: Bytes count to perform read operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * @EEPROM_DEF_SIZE: Fall back size of EEPROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * @EEPROM_DEF_ADDR: Defatul EEPROM address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * @EEPROM_TOUT: Timeout before retry read operation if eeprom is busy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #define EEPROM_OP_WRITE ((u8)0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define EEPROM_OP_READ ((u8)0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define EEPROM_USA ((u8)0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define EEPROM_NAERR ((u8)0x08)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #define EEPROM_LAERR ((u8)0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #define EEPROM_MSS ((u8)0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define EEPROM_WR_CNT ((u8)5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #define EEPROM_WRRD_CNT ((u8)4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #define EEPROM_RD_CNT ((u8)5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) #define EEPROM_DEF_SIZE ((u16)4096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #define EEPROM_DEF_ADDR ((u8)0x50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define EEPROM_TOUT (100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * CSR command macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * @CSR_DWE: Enable all four bytes of the operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * @CSR_OP_WRITE: CSR write operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * @CSR_OP_READ: CSR read operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * @CSR_RERR: Read operation error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * @CSR_WERR: Write operation error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * @CSR_WR_CNT: Bytes count to perform write operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * @CSR_WRRD_CNT: Bytes count to write before reading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * @CSR_RD_CNT: Bytes count to perform read operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * @CSR_MAX: Maximum CSR address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * @CSR_DEF: Default CSR address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * @CSR_REAL_ADDR: CSR real unshifted address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #define CSR_DWE ((u8)0x0F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) #define CSR_OP_WRITE ((u8)0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #define CSR_OP_READ ((u8)0x10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #define CSR_RERR ((u8)0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #define CSR_WERR ((u8)0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #define CSR_WR_CNT ((u8)7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #define CSR_WRRD_CNT ((u8)3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #define CSR_RD_CNT ((u8)7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define CSR_MAX ((u32)0x3FFFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) #define CSR_DEF ((u16)0x0000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) #define CSR_REAL_ADDR(val) ((unsigned int)val << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * IDT 89HPESx basic register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * @IDT_VIDDID_CSR: PCIe VID and DID of IDT 89HPESx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * @IDT_VID_MASK: Mask of VID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #define IDT_VIDDID_CSR ((u32)0x0000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) #define IDT_VID_MASK ((u32)0xFFFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * IDT 89HPESx can send NACK when new command is sent before previous one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * fininshed execution. In this case driver retries operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * certain times.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * @RETRY_CNT: Number of retries before giving up and fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * @idt_smb_safe: Generate a retry loop on corresponding SMBus method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) #define RETRY_CNT (128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) #define idt_smb_safe(ops, args...) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) int __retry = RETRY_CNT; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) s32 __sts; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) __sts = i2c_smbus_ ## ops ## _data(args); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) } while (__retry-- && __sts < 0); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) __sts; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /*===========================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * i2c bus level IO-operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) *===========================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * idt_smb_write_byte() - SMBus write method when I2C_SMBUS_BYTE_DATA operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * is only available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) * @seq: Sequence of data to be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static int idt_smb_write_byte(struct idt_89hpesx_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) const struct idt_smb_seq *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) s32 sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) u8 ccode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* Loop over the supplied data sending byte one-by-one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) for (idx = 0; idx < seq->bytecnt; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* Collect the command code byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) ccode = seq->ccode | CCODE_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (idx == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ccode |= CCODE_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (idx == seq->bytecnt - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) ccode |= CCODE_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* Send data to the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) sts = idt_smb_safe(write_byte, pdev->client, ccode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) seq->data[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (sts != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return (int)sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * idt_smb_read_byte() - SMBus read method when I2C_SMBUS_BYTE_DATA operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * is only available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * @seq: Buffer to read data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static int idt_smb_read_byte(struct idt_89hpesx_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct idt_smb_seq *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) s32 sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) u8 ccode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* Loop over the supplied buffer receiving byte one-by-one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) for (idx = 0; idx < seq->bytecnt; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) /* Collect the command code byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ccode = seq->ccode | CCODE_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (idx == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ccode |= CCODE_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (idx == seq->bytecnt - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) ccode |= CCODE_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* Read data from the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) sts = idt_smb_safe(read_byte, pdev->client, ccode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (sts < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return (int)sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) seq->data[idx] = (u8)sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * idt_smb_write_word() - SMBus write method when I2C_SMBUS_BYTE_DATA and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * I2C_FUNC_SMBUS_WORD_DATA operations are available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * @seq: Sequence of data to be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static int idt_smb_write_word(struct idt_89hpesx_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) const struct idt_smb_seq *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) s32 sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) u8 ccode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int idx, evencnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* Calculate the even count of data to send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) evencnt = seq->bytecnt - (seq->bytecnt % 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /* Loop over the supplied data sending two bytes at a time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) for (idx = 0; idx < evencnt; idx += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* Collect the command code byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) ccode = seq->ccode | CCODE_WORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (idx == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) ccode |= CCODE_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (idx == evencnt - 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) ccode |= CCODE_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* Send word data to the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) sts = idt_smb_safe(write_word, pdev->client, ccode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) *(u16 *)&seq->data[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (sts != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return (int)sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* If there is odd number of bytes then send just one last byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (seq->bytecnt != evencnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* Collect the command code byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ccode = seq->ccode | CCODE_BYTE | CCODE_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (idx == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ccode |= CCODE_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* Send byte data to the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) sts = idt_smb_safe(write_byte, pdev->client, ccode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) seq->data[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (sts != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return (int)sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * idt_smb_read_word() - SMBus read method when I2C_SMBUS_BYTE_DATA and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * I2C_FUNC_SMBUS_WORD_DATA operations are available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * @seq: Buffer to read data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static int idt_smb_read_word(struct idt_89hpesx_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct idt_smb_seq *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) s32 sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) u8 ccode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) int idx, evencnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /* Calculate the even count of data to send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) evencnt = seq->bytecnt - (seq->bytecnt % 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /* Loop over the supplied data reading two bytes at a time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) for (idx = 0; idx < evencnt; idx += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* Collect the command code byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ccode = seq->ccode | CCODE_WORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (idx == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ccode |= CCODE_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (idx == evencnt - 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ccode |= CCODE_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* Read word data from the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) sts = idt_smb_safe(read_word, pdev->client, ccode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (sts < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return (int)sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) *(u16 *)&seq->data[idx] = (u16)sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /* If there is odd number of bytes then receive just one last byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (seq->bytecnt != evencnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* Collect the command code byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) ccode = seq->ccode | CCODE_BYTE | CCODE_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (idx == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ccode |= CCODE_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /* Read last data byte from the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) sts = idt_smb_safe(read_byte, pdev->client, ccode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (sts < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return (int)sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) seq->data[idx] = (u8)sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * idt_smb_write_block() - SMBus write method when I2C_SMBUS_BLOCK_DATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * operation is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * @seq: Sequence of data to be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static int idt_smb_write_block(struct idt_89hpesx_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) const struct idt_smb_seq *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) u8 ccode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* Return error if too much data passed to send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (seq->bytecnt > I2C_SMBUS_BLOCK_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /* Collect the command code byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ccode = seq->ccode | CCODE_BLOCK | CCODE_START | CCODE_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /* Send block of data to the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return idt_smb_safe(write_block, pdev->client, ccode, seq->bytecnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) seq->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * idt_smb_read_block() - SMBus read method when I2C_SMBUS_BLOCK_DATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * operation is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * @seq: Buffer to read data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static int idt_smb_read_block(struct idt_89hpesx_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct idt_smb_seq *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) s32 sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) u8 ccode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /* Return error if too much data passed to send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (seq->bytecnt > I2C_SMBUS_BLOCK_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) /* Collect the command code byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ccode = seq->ccode | CCODE_BLOCK | CCODE_START | CCODE_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /* Read block of data from the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) sts = idt_smb_safe(read_block, pdev->client, ccode, seq->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (sts != seq->bytecnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return (sts < 0 ? sts : -ENODATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * idt_smb_write_i2c_block() - SMBus write method when I2C_SMBUS_I2C_BLOCK_DATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) * operation is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) * @seq: Sequence of data to be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * NOTE It's usual SMBus write block operation, except the actual data length is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * sent as first byte of data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) static int idt_smb_write_i2c_block(struct idt_89hpesx_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) const struct idt_smb_seq *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) u8 ccode, buf[I2C_SMBUS_BLOCK_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* Return error if too much data passed to send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (seq->bytecnt > I2C_SMBUS_BLOCK_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /* Collect the data to send. Length byte must be added prior the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) buf[0] = seq->bytecnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) memcpy(&buf[1], seq->data, seq->bytecnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /* Collect the command code byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) ccode = seq->ccode | CCODE_BLOCK | CCODE_START | CCODE_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* Send length and block of data to the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return idt_smb_safe(write_i2c_block, pdev->client, ccode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) seq->bytecnt + 1, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * idt_smb_read_i2c_block() - SMBus read method when I2C_SMBUS_I2C_BLOCK_DATA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * operation is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * @seq: Buffer to read data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * NOTE It's usual SMBus read block operation, except the actual data length is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * retrieved as first byte of data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) static int idt_smb_read_i2c_block(struct idt_89hpesx_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct idt_smb_seq *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) u8 ccode, buf[I2C_SMBUS_BLOCK_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) s32 sts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /* Return error if too much data passed to send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (seq->bytecnt > I2C_SMBUS_BLOCK_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /* Collect the command code byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) ccode = seq->ccode | CCODE_BLOCK | CCODE_START | CCODE_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* Read length and block of data from the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) sts = idt_smb_safe(read_i2c_block, pdev->client, ccode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) seq->bytecnt + 1, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (sts != seq->bytecnt + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return (sts < 0 ? sts : -ENODATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (buf[0] != seq->bytecnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /* Copy retrieved data to the output data buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) memcpy(seq->data, &buf[1], seq->bytecnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /*===========================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * EEPROM IO-operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) *===========================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * idt_eeprom_read_byte() - read just one byte from EEPROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * @memaddr: Start EEPROM memory address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * @data: Data to be written to EEPROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static int idt_eeprom_read_byte(struct idt_89hpesx_dev *pdev, u16 memaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) struct device *dev = &pdev->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct idt_eeprom_seq eeseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) struct idt_smb_seq smbseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) int ret, retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /* Initialize SMBus sequence fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) smbseq.ccode = pdev->iniccode | CCODE_EEPROM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) smbseq.data = (u8 *)&eeseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * Sometimes EEPROM may respond with NACK if it's busy with previous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * operation, so we need to perform a few attempts of read cycle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) retry = RETRY_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /* Send EEPROM memory address to read data from */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) smbseq.bytecnt = EEPROM_WRRD_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) eeseq.cmd = pdev->inieecmd | EEPROM_OP_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) eeseq.eeaddr = pdev->eeaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) eeseq.memaddr = cpu_to_le16(memaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) ret = pdev->smb_write(pdev, &smbseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) dev_err(dev, "Failed to init eeprom addr 0x%02hhx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) memaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /* Perform read operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) smbseq.bytecnt = EEPROM_RD_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) ret = pdev->smb_read(pdev, &smbseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) dev_err(dev, "Failed to read eeprom data 0x%02hhx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) memaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) /* Restart read operation if the device is busy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (retry && (eeseq.cmd & EEPROM_NAERR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) dev_dbg(dev, "EEPROM busy, retry reading after %d ms",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) EEPROM_TOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) msleep(EEPROM_TOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /* Check whether IDT successfully read data from EEPROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (eeseq.cmd & (EEPROM_NAERR | EEPROM_LAERR | EEPROM_MSS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) "Communication with eeprom failed, cmd 0x%hhx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) eeseq.cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /* Save retrieved data and exit the loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) *data = eeseq.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) } while (retry--);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /* Return the status of operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * idt_eeprom_write() - EEPROM write operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) * @memaddr: Start EEPROM memory address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * @len: Length of data to be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * @data: Data to be written to EEPROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static int idt_eeprom_write(struct idt_89hpesx_dev *pdev, u16 memaddr, u16 len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) const u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) struct device *dev = &pdev->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) struct idt_eeprom_seq eeseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) struct idt_smb_seq smbseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) u16 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /* Initialize SMBus sequence fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) smbseq.ccode = pdev->iniccode | CCODE_EEPROM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) smbseq.data = (u8 *)&eeseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) /* Send data byte-by-byte, checking if it is successfully written */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) for (idx = 0; idx < len; idx++, memaddr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /* Lock IDT SMBus device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) mutex_lock(&pdev->smb_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) /* Perform write operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) smbseq.bytecnt = EEPROM_WR_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) eeseq.cmd = pdev->inieecmd | EEPROM_OP_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) eeseq.eeaddr = pdev->eeaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) eeseq.memaddr = cpu_to_le16(memaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) eeseq.data = data[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) ret = pdev->smb_write(pdev, &smbseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) "Failed to write 0x%04hx:0x%02hhx to eeprom",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) memaddr, data[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) goto err_mutex_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * Check whether the data is successfully written by reading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * from the same EEPROM memory address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) eeseq.data = ~data[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) ret = idt_eeprom_read_byte(pdev, memaddr, &eeseq.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) goto err_mutex_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) /* Check whether the read byte is the same as written one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (eeseq.data != data[idx]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) dev_err(dev, "Values don't match 0x%02hhx != 0x%02hhx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) eeseq.data, data[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) goto err_mutex_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) /* Unlock IDT SMBus device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) err_mutex_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) mutex_unlock(&pdev->smb_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) * idt_eeprom_read() - EEPROM read operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * @memaddr: Start EEPROM memory address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * @len: Length of data to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * @buf: Buffer to read data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static int idt_eeprom_read(struct idt_89hpesx_dev *pdev, u16 memaddr, u16 len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) u16 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /* Read data byte-by-byte, retrying if it wasn't successful */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) for (idx = 0; idx < len; idx++, memaddr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /* Lock IDT SMBus device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) mutex_lock(&pdev->smb_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) /* Just read the byte to the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) ret = idt_eeprom_read_byte(pdev, memaddr, &buf[idx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) /* Unlock IDT SMBus device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) mutex_unlock(&pdev->smb_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) /* Return error if read operation failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) /*===========================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * CSR IO-operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) *===========================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * idt_csr_write() - CSR write operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * @csraddr: CSR address (with no two LS bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * @data: Data to be written to CSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static int idt_csr_write(struct idt_89hpesx_dev *pdev, u16 csraddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) const u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct device *dev = &pdev->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct idt_csr_seq csrseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct idt_smb_seq smbseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) /* Initialize SMBus sequence fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) smbseq.ccode = pdev->iniccode | CCODE_CSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) smbseq.data = (u8 *)&csrseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /* Lock IDT SMBus device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) mutex_lock(&pdev->smb_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) /* Perform write operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) smbseq.bytecnt = CSR_WR_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) csrseq.cmd = pdev->inicsrcmd | CSR_OP_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) csrseq.csraddr = cpu_to_le16(csraddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) csrseq.data = cpu_to_le32(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) ret = pdev->smb_write(pdev, &smbseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) dev_err(dev, "Failed to write 0x%04x: 0x%04x to csr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) CSR_REAL_ADDR(csraddr), data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) goto err_mutex_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) /* Send CSR address to read data from */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) smbseq.bytecnt = CSR_WRRD_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) csrseq.cmd = pdev->inicsrcmd | CSR_OP_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) ret = pdev->smb_write(pdev, &smbseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) dev_err(dev, "Failed to init csr address 0x%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) CSR_REAL_ADDR(csraddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) goto err_mutex_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /* Perform read operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) smbseq.bytecnt = CSR_RD_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) ret = pdev->smb_read(pdev, &smbseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) dev_err(dev, "Failed to read csr 0x%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) CSR_REAL_ADDR(csraddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) goto err_mutex_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /* Check whether IDT successfully retrieved CSR data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (csrseq.cmd & (CSR_RERR | CSR_WERR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) dev_err(dev, "IDT failed to perform CSR r/w");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) goto err_mutex_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) /* Unlock IDT SMBus device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) err_mutex_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) mutex_unlock(&pdev->smb_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) * idt_csr_read() - CSR read operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * @csraddr: CSR address (with no two LS bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) * @data: Data to be written to CSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) static int idt_csr_read(struct idt_89hpesx_dev *pdev, u16 csraddr, u32 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) struct device *dev = &pdev->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) struct idt_csr_seq csrseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct idt_smb_seq smbseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /* Initialize SMBus sequence fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) smbseq.ccode = pdev->iniccode | CCODE_CSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) smbseq.data = (u8 *)&csrseq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) /* Lock IDT SMBus device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) mutex_lock(&pdev->smb_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /* Send CSR register address before reading it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) smbseq.bytecnt = CSR_WRRD_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) csrseq.cmd = pdev->inicsrcmd | CSR_OP_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) csrseq.csraddr = cpu_to_le16(csraddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) ret = pdev->smb_write(pdev, &smbseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) dev_err(dev, "Failed to init csr address 0x%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) CSR_REAL_ADDR(csraddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) goto err_mutex_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) /* Perform read operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) smbseq.bytecnt = CSR_RD_CNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ret = pdev->smb_read(pdev, &smbseq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) dev_err(dev, "Failed to read csr 0x%04hx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) CSR_REAL_ADDR(csraddr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) goto err_mutex_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) /* Check whether IDT successfully retrieved CSR data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (csrseq.cmd & (CSR_RERR | CSR_WERR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) dev_err(dev, "IDT failed to perform CSR r/w");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) goto err_mutex_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) /* Save data retrieved from IDT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) *data = le32_to_cpu(csrseq.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) /* Unlock IDT SMBus device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) err_mutex_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) mutex_unlock(&pdev->smb_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) /*===========================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * Sysfs/debugfs-nodes IO-operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) *===========================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) * eeprom_write() - EEPROM sysfs-node write callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) * @filep: Pointer to the file system node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) * @kobj: Pointer to the kernel object related to the sysfs-node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) * @attr: Attributes of the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) * @buf: Buffer to write data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * @off: Offset at which data should be written to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) * @count: Number of bytes to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) static ssize_t eeprom_write(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) struct bin_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) char *buf, loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct idt_89hpesx_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /* Retrieve driver data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) pdev = dev_get_drvdata(kobj_to_dev(kobj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) /* Perform EEPROM write operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) ret = idt_eeprom_write(pdev, (u16)off, (u16)count, (u8 *)buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return (ret != 0 ? ret : count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) * eeprom_read() - EEPROM sysfs-node read callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) * @filep: Pointer to the file system node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * @kobj: Pointer to the kernel object related to the sysfs-node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) * @attr: Attributes of the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) * @buf: Buffer to write data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) * @off: Offset at which data should be written to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) * @count: Number of bytes to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) static ssize_t eeprom_read(struct file *filp, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) struct bin_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) char *buf, loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) struct idt_89hpesx_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /* Retrieve driver data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) pdev = dev_get_drvdata(kobj_to_dev(kobj));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) /* Perform EEPROM read operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) ret = idt_eeprom_read(pdev, (u16)off, (u16)count, (u8 *)buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return (ret != 0 ? ret : count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) * idt_dbgfs_csr_write() - CSR debugfs-node write callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) * @filep: Pointer to the file system file descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * @buf: Buffer to read data from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) * @count: Size of the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * @offp: Offset within the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * It accepts either "0x<reg addr>:0x<value>" for saving register address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * and writing value to specified DWORD register or "0x<reg addr>" for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) * just saving register address in order to perform next read operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) * WARNING No spaces are allowed. Incoming string must be strictly formated as:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) * "<reg addr>:<value>". Register address must be aligned within 4 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * (one DWORD).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static ssize_t idt_dbgfs_csr_write(struct file *filep, const char __user *ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) size_t count, loff_t *offp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) struct idt_89hpesx_dev *pdev = filep->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) char *colon_ch, *csraddr_str, *csrval_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) int ret, csraddr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) u32 csraddr, csrval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /* Copy data from User-space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) buf = kmalloc(count + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) ret = simple_write_to_buffer(buf, count, offp, ubuf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) goto free_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) buf[count] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) /* Find position of colon in the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) colon_ch = strnchr(buf, count, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * If there is colon passed then new CSR value should be parsed as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) * well, so allocate buffer for CSR address substring.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * If no colon is found, then string must have just one number with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) * no new CSR value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (colon_ch != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) csraddr_len = colon_ch - buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) csraddr_str =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) kmalloc(csraddr_len + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (csraddr_str == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) goto free_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) /* Copy the register address to the substring buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) strncpy(csraddr_str, buf, csraddr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) csraddr_str[csraddr_len] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) /* Register value must follow the colon */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) csrval_str = colon_ch + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) } else /* if (str_colon == NULL) */ {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) csraddr_str = (char *)buf; /* Just to shut warning up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) csraddr_len = strnlen(csraddr_str, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) csrval_str = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) /* Convert CSR address to u32 value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) ret = kstrtou32(csraddr_str, 0, &csraddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) goto free_csraddr_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) /* Check whether passed register address is valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (csraddr > CSR_MAX || !IS_ALIGNED(csraddr, SZ_4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) goto free_csraddr_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) /* Shift register address to the right so to have u16 address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) pdev->csr = (csraddr >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) /* Parse new CSR value and send it to IDT, if colon has been found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (colon_ch != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) ret = kstrtou32(csrval_str, 0, &csrval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) goto free_csraddr_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) ret = idt_csr_write(pdev, pdev->csr, csrval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) goto free_csraddr_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) /* Free memory only if colon has been found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) free_csraddr_str:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (colon_ch != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) kfree(csraddr_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) /* Free buffer allocated for data retrieved from User-space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) free_buf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return (ret != 0 ? ret : count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) * idt_dbgfs_csr_read() - CSR debugfs-node read callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) * @filep: Pointer to the file system file descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) * @buf: Buffer to write data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) * @count: Size of the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) * @offp: Offset within the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) * It just prints the pair "0x<reg addr>:0x<value>" to passed buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) #define CSRBUF_SIZE ((size_t)32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) static ssize_t idt_dbgfs_csr_read(struct file *filep, char __user *ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) size_t count, loff_t *offp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct idt_89hpesx_dev *pdev = filep->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) u32 csraddr, csrval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) char buf[CSRBUF_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) int ret, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) /* Perform CSR read operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) ret = idt_csr_read(pdev, pdev->csr, &csrval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) /* Shift register address to the left so to have real address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) csraddr = ((u32)pdev->csr << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) /* Print the "0x<reg addr>:0x<value>" to buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) size = snprintf(buf, CSRBUF_SIZE, "0x%05x:0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) (unsigned int)csraddr, (unsigned int)csrval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) /* Copy data to User-space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) return simple_read_from_buffer(ubuf, count, offp, buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) * eeprom_attribute - EEPROM sysfs-node attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) * NOTE Size will be changed in compliance with OF node. EEPROM attribute will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) * be read-only as well if the corresponding flag is specified in OF node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) static BIN_ATTR_RW(eeprom, EEPROM_DEF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) * csr_dbgfs_ops - CSR debugfs-node read/write operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) static const struct file_operations csr_dbgfs_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) .open = simple_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) .write = idt_dbgfs_csr_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) .read = idt_dbgfs_csr_read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) /*===========================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) * Driver init/deinit methods
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) *===========================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) * idt_set_defval() - disable EEPROM access by default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) static void idt_set_defval(struct idt_89hpesx_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) /* If OF info is missing then use next values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) pdev->eesize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) pdev->eero = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) pdev->inieecmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) pdev->eeaddr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static const struct i2c_device_id ee_ids[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * idt_ee_match_id() - check whether the node belongs to compatible EEPROMs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) static const struct i2c_device_id *idt_ee_match_id(struct fwnode_handle *fwnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) const struct i2c_device_id *id = ee_ids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) const char *compatible, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) char devname[I2C_NAME_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) ret = fwnode_property_read_string(fwnode, "compatible", &compatible);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) p = strchr(compatible, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) strlcpy(devname, p ? p + 1 : compatible, sizeof(devname));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) /* Search through the device name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) while (id->name[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (strcmp(devname, id->name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) return id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) * idt_get_fw_data() - get IDT i2c-device parameters from device tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) static void idt_get_fw_data(struct idt_89hpesx_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) struct device *dev = &pdev->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) struct fwnode_handle *fwnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) const struct i2c_device_id *ee_id = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) u32 eeprom_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) device_for_each_child_node(dev, fwnode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) ee_id = idt_ee_match_id(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) if (ee_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) dev_warn(dev, "Skip unsupported EEPROM device %pfw\n", fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) /* If there is no fwnode EEPROM device, then set zero size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (!ee_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) dev_warn(dev, "No fwnode, EEPROM access disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) idt_set_defval(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) /* Retrieve EEPROM size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) pdev->eesize = (u32)ee_id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) /* Get custom EEPROM address from 'reg' attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) ret = fwnode_property_read_u32(fwnode, "reg", &eeprom_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (ret || (eeprom_addr == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) dev_warn(dev, "No EEPROM reg found, use default address 0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) EEPROM_DEF_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) pdev->inieecmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) pdev->eeaddr = EEPROM_DEF_ADDR << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) pdev->inieecmd = EEPROM_USA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) pdev->eeaddr = eeprom_addr << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) /* Check EEPROM 'read-only' flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) if (fwnode_property_read_bool(fwnode, "read-only"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) pdev->eero = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) else /* if (!fwnode_property_read_bool(node, "read-only")) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) pdev->eero = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) fwnode_handle_put(fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) dev_info(dev, "EEPROM of %d bytes found by 0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) pdev->eesize, pdev->eeaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) * idt_create_pdev() - create and init data structure of the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) * @client: i2c client of IDT PCIe-switch device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) static struct idt_89hpesx_dev *idt_create_pdev(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) struct idt_89hpesx_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) /* Allocate memory for driver data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) pdev = devm_kmalloc(&client->dev, sizeof(struct idt_89hpesx_dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (pdev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) /* Initialize basic fields of the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) pdev->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) i2c_set_clientdata(client, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) /* Read firmware nodes information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) idt_get_fw_data(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /* Initialize basic CSR CMD field - use full DWORD-sized r/w ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) pdev->inicsrcmd = CSR_DWE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) pdev->csr = CSR_DEF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) /* Enable Packet Error Checking if it's supported by adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_PEC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) pdev->iniccode = CCODE_PEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) client->flags |= I2C_CLIENT_PEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) } else /* PEC is unsupported */ {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) pdev->iniccode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) return pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) * idt_free_pdev() - free data structure of the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) static void idt_free_pdev(struct idt_89hpesx_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) /* Clear driver data from device private field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) i2c_set_clientdata(pdev->client, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) * idt_set_smbus_ops() - set supported SMBus operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) * Return status of smbus check operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) static int idt_set_smbus_ops(struct idt_89hpesx_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) struct i2c_adapter *adapter = pdev->client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) struct device *dev = &pdev->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) /* Check i2c adapter read functionality */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (i2c_check_functionality(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) I2C_FUNC_SMBUS_READ_BLOCK_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) pdev->smb_read = idt_smb_read_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) dev_dbg(dev, "SMBus block-read op chosen");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) } else if (i2c_check_functionality(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) pdev->smb_read = idt_smb_read_i2c_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) dev_dbg(dev, "SMBus i2c-block-read op chosen");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) } else if (i2c_check_functionality(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) I2C_FUNC_SMBUS_READ_WORD_DATA) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) i2c_check_functionality(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) pdev->smb_read = idt_smb_read_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) dev_warn(dev, "Use slow word/byte SMBus read ops");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) } else if (i2c_check_functionality(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) pdev->smb_read = idt_smb_read_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) dev_warn(dev, "Use slow byte SMBus read op");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) } else /* no supported smbus read operations */ {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) dev_err(dev, "No supported SMBus read op");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return -EPFNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) /* Check i2c adapter write functionality */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (i2c_check_functionality(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) pdev->smb_write = idt_smb_write_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) dev_dbg(dev, "SMBus block-write op chosen");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) } else if (i2c_check_functionality(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) pdev->smb_write = idt_smb_write_i2c_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) dev_dbg(dev, "SMBus i2c-block-write op chosen");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) } else if (i2c_check_functionality(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) I2C_FUNC_SMBUS_WRITE_WORD_DATA) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) i2c_check_functionality(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) pdev->smb_write = idt_smb_write_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) dev_warn(dev, "Use slow word/byte SMBus write op");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) } else if (i2c_check_functionality(adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) pdev->smb_write = idt_smb_write_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) dev_warn(dev, "Use slow byte SMBus write op");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) } else /* no supported smbus write operations */ {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) dev_err(dev, "No supported SMBus write op");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) return -EPFNOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) /* Initialize IDT SMBus slave interface mutex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) mutex_init(&pdev->smb_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) * idt_check_dev() - check whether it's really IDT 89HPESx device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) * Return status of i2c adapter check operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) static int idt_check_dev(struct idt_89hpesx_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) struct device *dev = &pdev->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) u32 viddid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) /* Read VID and DID directly from IDT memory space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) ret = idt_csr_read(pdev, IDT_VIDDID_CSR, &viddid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) dev_err(dev, "Failed to read VID/DID");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) /* Check whether it's IDT device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if ((viddid & IDT_VID_MASK) != PCI_VENDOR_ID_IDT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) dev_err(dev, "Got unsupported VID/DID: 0x%08x", viddid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) dev_info(dev, "Found IDT 89HPES device VID:0x%04x, DID:0x%04x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) (viddid & IDT_VID_MASK), (viddid >> 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) * idt_create_sysfs_files() - create sysfs attribute files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) * Return status of operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) static int idt_create_sysfs_files(struct idt_89hpesx_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) struct device *dev = &pdev->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) /* Don't do anything if EEPROM isn't accessible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (pdev->eesize == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) dev_dbg(dev, "Skip creating sysfs-files");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) /* Allocate memory for attribute file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) pdev->ee_file = devm_kmalloc(dev, sizeof(*pdev->ee_file), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) if (!pdev->ee_file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) /* Copy the declared EEPROM attr structure to change some of fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) memcpy(pdev->ee_file, &bin_attr_eeprom, sizeof(*pdev->ee_file));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) /* In case of read-only EEPROM get rid of write ability */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) if (pdev->eero) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) pdev->ee_file->attr.mode &= ~0200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) pdev->ee_file->write = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) /* Create EEPROM sysfs file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) pdev->ee_file->size = pdev->eesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) ret = sysfs_create_bin_file(&dev->kobj, pdev->ee_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) dev_err(dev, "Failed to create EEPROM sysfs-node");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) * idt_remove_sysfs_files() - remove sysfs attribute files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) static void idt_remove_sysfs_files(struct idt_89hpesx_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) struct device *dev = &pdev->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) /* Don't do anything if EEPROM wasn't accessible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (pdev->eesize == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) /* Remove EEPROM sysfs file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) sysfs_remove_bin_file(&dev->kobj, pdev->ee_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) * idt_create_dbgfs_files() - create debugfs files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) #define CSRNAME_LEN ((size_t)32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) static void idt_create_dbgfs_files(struct idt_89hpesx_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) struct i2c_client *cli = pdev->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) char fname[CSRNAME_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) /* Create Debugfs directory for CSR file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) snprintf(fname, CSRNAME_LEN, "%d-%04hx", cli->adapter->nr, cli->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) pdev->csr_dir = debugfs_create_dir(fname, csr_dbgdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) /* Create Debugfs file for CSR read/write operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) debugfs_create_file(cli->name, 0600, pdev->csr_dir, pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) &csr_dbgfs_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) * idt_remove_dbgfs_files() - remove debugfs files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) * @pdev: Pointer to the driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) static void idt_remove_dbgfs_files(struct idt_89hpesx_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) /* Remove CSR directory and it sysfs-node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) debugfs_remove_recursive(pdev->csr_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) * idt_probe() - IDT 89HPESx driver probe() callback method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) static int idt_probe(struct i2c_client *client, const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) struct idt_89hpesx_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) /* Create driver data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) pdev = idt_create_pdev(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) if (IS_ERR(pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) return PTR_ERR(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) /* Set SMBus operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) ret = idt_set_smbus_ops(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) goto err_free_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) /* Check whether it is truly IDT 89HPESx device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) ret = idt_check_dev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) goto err_free_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) /* Create sysfs files */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) ret = idt_create_sysfs_files(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) goto err_free_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) /* Create debugfs files */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) idt_create_dbgfs_files(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) err_free_pdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) idt_free_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) * idt_remove() - IDT 89HPESx driver remove() callback method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) static int idt_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) struct idt_89hpesx_dev *pdev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) /* Remove debugfs files first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) idt_remove_dbgfs_files(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) /* Remove sysfs files */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) idt_remove_sysfs_files(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) /* Discard driver data structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) idt_free_pdev(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) * ee_ids - array of supported EEPROMs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) static const struct i2c_device_id ee_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) { "24c32", 4096},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) { "24c64", 8192},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) { "24c128", 16384},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) { "24c256", 32768},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) { "24c512", 65536},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) MODULE_DEVICE_TABLE(i2c, ee_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) * idt_ids - supported IDT 89HPESx devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) static const struct i2c_device_id idt_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) { "89hpes8nt2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) { "89hpes12nt3", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) { "89hpes24nt6ag2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) { "89hpes32nt8ag2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) { "89hpes32nt8bg2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) { "89hpes12nt12g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) { "89hpes16nt16g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) { "89hpes24nt24g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) { "89hpes32nt24ag2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) { "89hpes32nt24bg2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) { "89hpes12n3", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) { "89hpes12n3a", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) { "89hpes24n3", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) { "89hpes24n3a", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) { "89hpes32h8", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) { "89hpes32h8g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) { "89hpes48h12", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) { "89hpes48h12g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) { "89hpes48h12ag2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) { "89hpes16h16", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) { "89hpes22h16", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) { "89hpes22h16g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) { "89hpes34h16", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) { "89hpes34h16g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) { "89hpes64h16", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) { "89hpes64h16g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) { "89hpes64h16ag2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) /* { "89hpes3t3", 0 }, // No SMBus-slave iface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) { "89hpes12t3g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) { "89hpes24t3g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) /* { "89hpes4t4", 0 }, // No SMBus-slave iface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) { "89hpes16t4", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) { "89hpes4t4g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) { "89hpes10t4g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) { "89hpes16t4g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) { "89hpes16t4ag2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) { "89hpes5t5", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) { "89hpes6t5", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) { "89hpes8t5", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) { "89hpes8t5a", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) { "89hpes24t6", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) { "89hpes6t6g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) { "89hpes24t6g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) { "89hpes16t7", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) { "89hpes32t8", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) { "89hpes32t8g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) { "89hpes48t12", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) { "89hpes48t12g2", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) { /* END OF LIST */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) MODULE_DEVICE_TABLE(i2c, idt_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) static const struct of_device_id idt_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) { .compatible = "idt,89hpes8nt2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) { .compatible = "idt,89hpes12nt3", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) { .compatible = "idt,89hpes24nt6ag2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) { .compatible = "idt,89hpes32nt8ag2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) { .compatible = "idt,89hpes32nt8bg2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) { .compatible = "idt,89hpes12nt12g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) { .compatible = "idt,89hpes16nt16g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) { .compatible = "idt,89hpes24nt24g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) { .compatible = "idt,89hpes32nt24ag2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) { .compatible = "idt,89hpes32nt24bg2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) { .compatible = "idt,89hpes12n3", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) { .compatible = "idt,89hpes12n3a", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) { .compatible = "idt,89hpes24n3", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) { .compatible = "idt,89hpes24n3a", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) { .compatible = "idt,89hpes32h8", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) { .compatible = "idt,89hpes32h8g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) { .compatible = "idt,89hpes48h12", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) { .compatible = "idt,89hpes48h12g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) { .compatible = "idt,89hpes48h12ag2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) { .compatible = "idt,89hpes16h16", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) { .compatible = "idt,89hpes22h16", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) { .compatible = "idt,89hpes22h16g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) { .compatible = "idt,89hpes34h16", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) { .compatible = "idt,89hpes34h16g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) { .compatible = "idt,89hpes64h16", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) { .compatible = "idt,89hpes64h16g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) { .compatible = "idt,89hpes64h16ag2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) { .compatible = "idt,89hpes12t3g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) { .compatible = "idt,89hpes24t3g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) { .compatible = "idt,89hpes16t4", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) { .compatible = "idt,89hpes4t4g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) { .compatible = "idt,89hpes10t4g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) { .compatible = "idt,89hpes16t4g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) { .compatible = "idt,89hpes16t4ag2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) { .compatible = "idt,89hpes5t5", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) { .compatible = "idt,89hpes6t5", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) { .compatible = "idt,89hpes8t5", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) { .compatible = "idt,89hpes8t5a", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) { .compatible = "idt,89hpes24t6", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) { .compatible = "idt,89hpes6t6g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) { .compatible = "idt,89hpes24t6g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) { .compatible = "idt,89hpes16t7", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) { .compatible = "idt,89hpes32t8", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) { .compatible = "idt,89hpes32t8g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) { .compatible = "idt,89hpes48t12", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) { .compatible = "idt,89hpes48t12g2", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) MODULE_DEVICE_TABLE(of, idt_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) * idt_driver - IDT 89HPESx driver structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) static struct i2c_driver idt_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) .name = IDT_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) .of_match_table = idt_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) .probe = idt_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) .remove = idt_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) .id_table = idt_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) * idt_init() - IDT 89HPESx driver init() callback method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) static int __init idt_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) /* Create Debugfs directory first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if (debugfs_initialized())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) csr_dbgdir = debugfs_create_dir("idt_csr", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) /* Add new i2c-device driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) return i2c_add_driver(&idt_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) module_init(idt_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) * idt_exit() - IDT 89HPESx driver exit() callback method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) static void __exit idt_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) /* Discard debugfs directory and all files if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) debugfs_remove_recursive(csr_dbgdir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) /* Unregister i2c-device driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) i2c_del_driver(&idt_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) module_exit(idt_exit);