[media] media: rc: nuvoton-cir: improve chip detection
authorHeiner Kallweit <hkallweit1@gmail.com>
Thu, 29 Oct 2015 21:21:38 +0000 (19:21 -0200)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Thu, 19 Nov 2015 11:35:32 +0000 (09:35 -0200)
Make the chip detection code more similar to the one used for the
same chips in watchdog/w83627hf_wdt.c and hwmon/w83627ehf.c.

Apart from better maintainability we gain
- unified naming of chips (e.g. 677C -> NCT6776F)
- driver works with all revisions of the chips
  (least 4 bits of id are masked)

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
drivers/media/rc/nuvoton-cir.c
drivers/media/rc/nuvoton-cir.h

index a382e17e976c295395612fe540d4531faf3f5080..c5c238ba5618275e2a27d02c2e9e47eb1b2ad9a4 100644 (file)
 
 #include "nuvoton-cir.h"
 
+static const struct nvt_chip nvt_chips[] = {
+       { "w83667hg", NVT_W83667HG },
+       { "NCT6775F", NVT_6775F },
+       { "NCT6776F", NVT_6776F },
+};
+
+static inline bool is_w83667hg(struct nvt_dev *nvt)
+{
+       return nvt->chip_ver == NVT_W83667HG;
+}
+
 /* write val to config reg */
 static inline void nvt_cr_write(struct nvt_dev *nvt, u8 val, u8 reg)
 {
@@ -224,63 +235,53 @@ static void cir_wake_dump_regs(struct nvt_dev *nvt)
        pr_cont("\n");
 }
 
+static inline const char *nvt_find_chip(struct nvt_dev *nvt, int id)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(nvt_chips); i++)
+               if ((id & SIO_ID_MASK) == nvt_chips[i].chip_ver) {
+                       nvt->chip_ver = nvt_chips[i].chip_ver;
+                       return nvt_chips[i].name;
+               }
+
+       return NULL;
+}
+
+
 /* detect hardware features */
 static int nvt_hw_detect(struct nvt_dev *nvt)
 {
-       u8 chip_major, chip_minor;
-       char chip_id[12];
-       bool chip_unknown = false;
+       const char *chip_name;
+       int chip_id;
 
        nvt_efm_enable(nvt);
 
        /* Check if we're wired for the alternate EFER setup */
-       chip_major = nvt_cr_read(nvt, CR_CHIP_ID_HI);
-       if (chip_major == 0xff) {
+       nvt->chip_major = nvt_cr_read(nvt, CR_CHIP_ID_HI);
+       if (nvt->chip_major == 0xff) {
                nvt->cr_efir = CR_EFIR2;
                nvt->cr_efdr = CR_EFDR2;
                nvt_efm_enable(nvt);
-               chip_major = nvt_cr_read(nvt, CR_CHIP_ID_HI);
+               nvt->chip_major = nvt_cr_read(nvt, CR_CHIP_ID_HI);
        }
 
-       chip_minor = nvt_cr_read(nvt, CR_CHIP_ID_LO);
-
-       /* these are the known working chip revisions... */
-       switch (chip_major) {
-       case CHIP_ID_HIGH_667:
-               strcpy(chip_id, "w83667hg\0");
-               if (chip_minor != CHIP_ID_LOW_667)
-                       chip_unknown = true;
-               break;
-       case CHIP_ID_HIGH_677B:
-               strcpy(chip_id, "w83677hg\0");
-               if (chip_minor != CHIP_ID_LOW_677B2 &&
-                   chip_minor != CHIP_ID_LOW_677B3)
-                       chip_unknown = true;
-               break;
-       case CHIP_ID_HIGH_677C:
-               strcpy(chip_id, "w83677hg-c\0");
-               if (chip_minor != CHIP_ID_LOW_677C)
-                       chip_unknown = true;
-               break;
-       default:
-               strcpy(chip_id, "w836x7hg\0");
-               chip_unknown = true;
-               break;
-       }
+       nvt->chip_minor = nvt_cr_read(nvt, CR_CHIP_ID_LO);
+
+       chip_id = nvt->chip_major << 8 | nvt->chip_minor;
+       chip_name = nvt_find_chip(nvt, chip_id);
 
        /* warn, but still let the driver load, if we don't know this chip */
-       if (chip_unknown)
-               nvt_pr(KERN_WARNING, "%s: unknown chip, id: 0x%02x 0x%02x, "
-                      "it may not work...", chip_id, chip_major, chip_minor);
+       if (!chip_name)
+               nvt_pr(KERN_WARNING,
+                      "unknown chip, id: 0x%02x 0x%02x, it may not work...",
+                      nvt->chip_major, nvt->chip_minor);
        else
-               nvt_dbg("%s: chip id: 0x%02x 0x%02x",
-                       chip_id, chip_major, chip_minor);
+               nvt_dbg("found %s or compatible: chip id: 0x%02x 0x%02x",
+                       chip_name, nvt->chip_major, nvt->chip_minor);
 
        nvt_efm_disable(nvt);
 
-       nvt->chip_major = chip_major;
-       nvt->chip_minor = chip_minor;
-
        return 0;
 }
 
@@ -288,7 +289,7 @@ static void nvt_cir_ldev_init(struct nvt_dev *nvt)
 {
        u8 val, psreg, psmask, psval;
 
-       if (nvt->chip_major == CHIP_ID_HIGH_667) {
+       if (is_w83667hg(nvt)) {
                psreg = CR_MULTIFUNC_PIN_SEL;
                psmask = MULTIFUNC_PIN_SEL_MASK;
                psval = MULTIFUNC_ENABLE_CIR | MULTIFUNC_ENABLE_CIRWB;
index e1cf23c3875b16ead52464d4e6ad3c479fd1e951..81b5a09abd3c3ae4741374d77b91757a22cfa277 100644 (file)
@@ -64,6 +64,20 @@ static int debug;
 #define TX_BUF_LEN 256
 #define RX_BUF_LEN 32
 
+#define SIO_ID_MASK 0xfff0
+
+enum nvt_chip_ver {
+       NVT_UNKNOWN     = 0,
+       NVT_W83667HG    = 0xa510,
+       NVT_6775F       = 0xb470,
+       NVT_6776F       = 0xc330
+};
+
+struct nvt_chip {
+       const char *name;
+       enum nvt_chip_ver chip_ver;
+};
+
 struct nvt_dev {
        struct pnp_dev *pdev;
        struct rc_dev *rdev;
@@ -93,6 +107,7 @@ struct nvt_dev {
        int cir_irq;
        int cir_wake_irq;
 
+       enum nvt_chip_ver chip_ver;
        /* hardware id */
        u8 chip_major;
        u8 chip_minor;
@@ -326,15 +341,6 @@ struct nvt_dev {
 #define EFER_EFM_ENABLE                0x87
 #define EFER_EFM_DISABLE       0xaa
 
-/* Chip IDs found in CR_CHIP_ID_{HI,LO} */
-#define CHIP_ID_HIGH_667       0xa5
-#define CHIP_ID_HIGH_677B      0xb4
-#define CHIP_ID_HIGH_677C      0xc3
-#define CHIP_ID_LOW_667                0x13
-#define CHIP_ID_LOW_677B2      0x72
-#define CHIP_ID_LOW_677B3      0x73
-#define CHIP_ID_LOW_677C       0x33
-
 /* Config regs we need to care about */
 #define CR_SOFTWARE_RESET      0x02
 #define CR_LOGICAL_DEV_SEL     0x07