n810: Add retu/tahvo userspace interface debugging
authorMichael Büsch <mb@bu3sch.de>
Sat, 21 Aug 2010 15:43:39 +0000 (15:43 +0000)
committerMichael Büsch <mb@bu3sch.de>
Sat, 21 Aug 2010 15:43:39 +0000 (15:43 +0000)
SVN-Revision: 22747

target/linux/omap24xx/config-2.6.35
target/linux/omap24xx/patches-2.6.35/510-retu-tahvo-user-debugging.patch [new file with mode: 0644]

index e844ad80b497fb810f337311e6371a3da0def8f6..92043b64d8a3597ac45d9d8f8afed8e4b6fc1c46 100644 (file)
@@ -67,10 +67,12 @@ CONFIG_CBUS_RETU_HEADSET=y
 CONFIG_CBUS_RETU_POWERBUTTON=y
 CONFIG_CBUS_RETU_RTC=y
 CONFIG_CBUS_RETU_USER=y
+CONFIG_CBUS_RETU_USER_DEBUG=y
 CONFIG_CBUS_RETU_WDT=y
 CONFIG_CBUS_TAHVO=y
 # CONFIG_CBUS_TAHVO_USB is not set
 CONFIG_CBUS_TAHVO_USER=y
+CONFIG_CBUS_TAHVO_USER_DEBUG=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_CMDLINE="root=/dev/mmcblk0p1 rootfstype=ext3,ext2,squashfs,jffs2 console=tty0 console=ttyS2,115200n8"
 CONFIG_CMDLINE_FORCE=y
@@ -295,7 +297,7 @@ CONFIG_LEDS_TRIGGER_GPIO=y
 # CONFIG_LIS3L02DQ is not set
 CONFIG_LLC=m
 CONFIG_LOCK_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=17
+CONFIG_LOG_BUF_SHIFT=18
 CONFIG_LZO_COMPRESS=y
 CONFIG_LZO_DECOMPRESS=y
 CONFIG_MACH_NOKIA_N800=y
diff --git a/target/linux/omap24xx/patches-2.6.35/510-retu-tahvo-user-debugging.patch b/target/linux/omap24xx/patches-2.6.35/510-retu-tahvo-user-debugging.patch
new file mode 100644 (file)
index 0000000..0e4cd12
--- /dev/null
@@ -0,0 +1,324 @@
+---
+ drivers/cbus/Kconfig      |    8 +++
+ drivers/cbus/retu-user.c  |  117 +++++++++++++++++++++++++++++++++++++++++++++-
+ drivers/cbus/tahvo-user.c |   75 +++++++++++++++++++++++++++++
+ 3 files changed, 198 insertions(+), 2 deletions(-)
+
+--- linux-2.6.35.orig/drivers/cbus/Kconfig
++++ linux-2.6.35/drivers/cbus/Kconfig
+@@ -28,6 +28,10 @@ config CBUS_TAHVO_USER
+         If you want support for Tahvo's user space read/write etc. functions,
+         you should say Y here.
++config CBUS_TAHVO_USER_DEBUG
++      depends on CBUS_TAHVO_USER
++      bool "Enable Tahvo user space interface debugging"
++
+ config CBUS_TAHVO_USB
+       depends on CBUS_TAHVO && USB
+       tristate "Support for Tahvo USB transceiver"
+@@ -56,6 +60,10 @@ config CBUS_RETU_USER
+         If you want support for Retu's user space read/write etc. functions,
+         you should say Y here.
++config CBUS_RETU_USER_DEBUG
++      depends on CBUS_RETU_USER
++      bool "Enable Retu user space interface debugging"
++
+ config CBUS_RETU_POWERBUTTON
+       depends on CBUS_RETU
+       bool "Support for Retu power button"
+--- linux-2.6.35.orig/drivers/cbus/retu-user.c
++++ linux-2.6.35/drivers/cbus/retu-user.c
+@@ -46,6 +46,12 @@
+ #define PFX                   "retu-user: "
++#ifdef CONFIG_CBUS_RETU_USER_DEBUG
++# define dprintk(fmt, x...)   printk(KERN_DEBUG PFX fmt, x)
++#else
++# define dprintk(fmt, x...)   do { } while (0)
++#endif
++
+ /* Bitmap for marking the interrupt sources as having the handlers */
+ static u32 retu_irq_bits;
+@@ -105,6 +111,94 @@ static const u8 retu_access_bits[] = {
+       3
+ };
++#ifdef CONFIG_CBUS_RETU_USER_DEBUG
++static const char * reg_access_text(unsigned int reg)
++{
++      if (WARN_ON(reg >= ARRAY_SIZE(retu_access_bits)))
++              return "X";
++      switch (retu_access_bits[reg]) {
++      case READ_ONLY:
++              return "R";
++      case WRITE_ONLY:
++              return "W";
++      case READ_WRITE:
++              return "RW";
++      case TOGGLE:
++              return "T";
++      }
++      return "X";
++}
++
++static const char * reg_name(unsigned int reg)
++{
++      static const char *names[] = {
++              [RETU_REG_ASICR]        = "ASIC ID & revision",
++              [RETU_REG_IDR]          = "Interrupt ID",
++              [RETU_REG_IMR]          = "Interrupt mask",
++              [RETU_REG_RTCDSR]       = "RTC seconds register",
++              [RETU_REG_RTCHMR]       = "RTC hours and minutes register",
++              [RETU_REG_RTCHMAR]      = "hours and minutes alarm and time set register",
++              [RETU_REG_RTCCALR]      = "RTC calibration register",
++              [RETU_REG_ADCR]         = "ADC result",
++              [RETU_REG_ADCSCR]       = "ADC sample ctrl",
++              [RETU_REG_CC1]          = "Common control register 1",
++              [RETU_REG_CC2]          = "Common control register 2",
++              [RETU_REG_CTRL_CLR]     = "Regulator clear register",
++              [RETU_REG_CTRL_SET]     = "Regulator set register",
++              [RETU_REG_STATUS]       = "Status register",
++              [RETU_REG_WATCHDOG]     = "Watchdog register",
++              [RETU_REG_AUDTXR]       = "Audio Codec Tx register",
++              [0x14]                  = "Charger detect?",
++      };
++      const char *name;
++
++      if (reg >= ARRAY_SIZE(names))
++              return "";
++      name = names[reg];
++      if (!name)
++              return "";
++      return name;
++}
++
++static const char * adc_chan_name(unsigned int chan)
++{
++      static const char *names[] = {
++              [0x05]          = "Headset hook detect",
++      };
++      const char *name;
++
++      if (chan >= ARRAY_SIZE(names))
++              return "";
++      name = names[chan];
++      if (!name)
++              return "";
++      return name;
++}
++
++static const char * retu_irq_name(unsigned int id)
++{
++      static const char *names[] = {
++              [RETU_INT_PWR]          = "Power",
++              [RETU_INT_CHAR]         = "Char",
++              [RETU_INT_RTCS]         = "RTCS",
++              [RETU_INT_RTCM]         = "RTCM",
++              [RETU_INT_RTCD]         = "RTCD",
++              [RETU_INT_RTCA]         = "RTCA",
++              [RETU_INT_HOOK]         = "Hook",
++              [RETU_INT_HEAD]         = "Head",
++              [RETU_INT_ADCS]         = "ADC timer",
++      };
++      const char *name;
++
++      if (id >= ARRAY_SIZE(names))
++              return "";
++      name = names[id];
++      if (!name)
++              return "";
++      return name;
++}
++#endif
++
+ /*
+  * The handler for all RETU interrupts.
+  *
+@@ -157,6 +251,8 @@ static int retu_user_subscribe_to_irq(in
+       /* Mark that this interrupt has a handler */
+       retu_irq_bits |= 1 << id;
++      dprintk("Subscribed to IRQ %d (%s)\n", id, retu_irq_name(id));
++
+       return 0;
+ }
+@@ -216,6 +312,10 @@ static int retu_user_write_with_mask(u32
+       /* Generate new value */
+       tmp = (tmp & ~MASK(field)) | (value & MASK(field));
++
++      dprintk("{WRITE %s} 0x%02X(%s) <= msk 0x%04X, val 0x%04X ==> res 0x%04X\n",
++              reg_name(reg), reg, reg_access_text(reg), MASK(field), value, tmp);
++
+       /* Write data to RETU */
+       retu_write_reg(reg, tmp);
+       spin_unlock_irqrestore(&retu_lock, flags);
+@@ -244,6 +344,9 @@ static u32 retu_user_read_with_mask(u32
+       /* Read the register */
+       value = retu_read_reg(reg) & mask;
++      dprintk("{READ %s} 0x%02X(%s) <= msk 0x%04X ==> res 0x%04X\n",
++              reg_name(reg), reg, reg_access_text(reg), mask, value);
++
+       /* Right justify value */
+       while (!(mask & 1)) {
+               value = value >> 1;
+@@ -274,7 +377,7 @@ static int retu_ioctl(struct inode *inod
+                     unsigned int cmd, unsigned long arg)
+ {
+       struct retu_tahvo_write_parms par;
+-      int ret;
++      int ret, result;
+       switch (cmd) {
+       case URT_IOCT_IRQ_SUBSCR:
+@@ -291,7 +394,15 @@ static int retu_ioctl(struct inode *inod
+                       printk(KERN_ERR "copy_to_user failed: %d\n", ret);
+               break;
+       case RETU_IOCH_ADC_READ:
+-              return retu_read_adc(arg);
++              result = retu_read_adc(arg);
++              if (result >= 0) {
++                      dprintk("{READ-ADC %s} chan 0x%02lX ==> result 0x%04X\n",
++                              adc_chan_name(arg), arg, result);
++              } else {
++                      dprintk("{READ-ADC %s} chan 0x%02lX ==> failed %d\n",
++                              adc_chan_name(arg), arg, result);
++              }
++              return result;
+       default:
+               return -ENOIOCTLCMD;
+       }
+@@ -333,6 +444,8 @@ static ssize_t retu_read(struct file *fi
+               list_move(&irq->node, &retu_irqs_reserve);
+               spin_unlock_irqrestore(&retu_irqs_lock, flags);
++              dprintk("{IRQ %s} %d delivered\n", retu_irq_name(irq_id), (int)irq_id);
++
+               ret = copy_to_user(buf + i * sizeof(irq_id), &irq_id,
+                                  sizeof(irq_id));
+               if (ret)
+--- linux-2.6.35.orig/drivers/cbus/tahvo-user.c
++++ linux-2.6.35/drivers/cbus/tahvo-user.c
+@@ -46,6 +46,12 @@
+ #define PFX                   "tahvo-user: "
++#ifdef CONFIG_CBUS_TAHVO_USER_DEBUG
++# define dprintk(fmt, x...)   printk(KERN_DEBUG PFX fmt, x)
++#else
++# define dprintk(fmt, x...)   do { } while (0)
++#endif
++
+ /* Bitmap for marking the interrupt sources as having the handlers */
+ static u32 tahvo_irq_bits;
+@@ -87,6 +93,64 @@ static const u8 tahvo_access_bits[] = {
+       1
+ };
++#ifdef CONFIG_CBUS_TAHVO_USER_DEBUG
++static const char * reg_access_text(unsigned int reg)
++{
++      if (WARN_ON(reg >= ARRAY_SIZE(tahvo_access_bits)))
++              return "X";
++      switch (tahvo_access_bits[reg]) {
++      case READ_ONLY:
++              return "R";
++      case WRITE_ONLY:
++              return "W";
++      case READ_WRITE:
++              return "RW";
++      case TOGGLE:
++              return "T";
++      }
++      return "X";
++}
++
++static const char * reg_name(unsigned int reg)
++{
++      static const char *names[] = {
++              [TAHVO_REG_ASICR]       = "ASIC ID & revision",
++              [TAHVO_REG_IDR]         = "Interrupt ID",
++              [TAHVO_REG_IDSR]        = "Interrupt status",
++              [TAHVO_REG_IMR]         = "Interrupt mask",
++              [TAHVO_REG_LEDPWMR]     = "LED PWM",
++              [TAHVO_REG_USBR]        = "USB control",
++              [0x04]                  = "Charge current control?",
++              [0x08]                  = "Charge ctl 1?",
++              [0x0C]                  = "Charge ctl 2?",
++              [0x0D]                  = "Battery current ADC?",
++      };
++      const char *name;
++
++      if (reg >= ARRAY_SIZE(names))
++              return "";
++      name = names[reg];
++      if (!name)
++              return "";
++      return name;
++}
++
++static const char * tahvo_irq_name(unsigned int id)
++{
++      static const char *names[] = {
++              [TAHVO_INT_VBUSON]      = "VBUSON",
++      };
++      const char *name;
++
++      if (id >= ARRAY_SIZE(names))
++              return "";
++      name = names[id];
++      if (!name)
++              return "";
++      return name;
++}
++#endif
++
+ /*
+  * The handler for all TAHVO interrupts.
+  *
+@@ -142,6 +206,8 @@ static int tahvo_user_subscribe_to_irq(i
+       /* Mark that this interrupt has a handler */
+       tahvo_irq_bits |= 1 << id;
++      dprintk("Subscribed to IRQ %d (%s)\n", id, tahvo_irq_name(id));
++
+       return 0;
+ }
+@@ -200,6 +266,10 @@ static int tahvo_user_write_with_mask(u3
+       }
+       /* Generate a new value */
+       tmp = (tmp & ~MASK(field)) | (value & MASK(field));
++
++      dprintk("{WRITE %s} 0x%02X(%s) <= msk 0x%04X, val 0x%04X ==> res 0x%04X\n",
++              reg_name(reg), reg, reg_access_text(reg), MASK(field), value, tmp);
++
+       /* Write data to TAHVO */
+       tahvo_write_reg(reg, tmp);
+       spin_unlock_irqrestore(&tahvo_lock, flags);
+@@ -228,6 +298,9 @@ static u32 tahvo_user_read_with_mask(u32
+       /* Read the register */
+       value = tahvo_read_reg(reg) & mask;
++      dprintk("{READ %s} 0x%02X(%s) <= msk 0x%04X ==> res 0x%04X\n",
++              reg_name(reg), reg, reg_access_text(reg), mask, value);
++
+       /* Right justify value */
+       while (!(mask & 1)) {
+               value = value >> 1;
+@@ -315,6 +388,8 @@ static ssize_t tahvo_read(struct file *f
+               list_move(&irq->node, &tahvo_irqs_reserve);
+               spin_unlock_irqrestore(&tahvo_irqs_lock, flags);
++              dprintk("{IRQ %s} %d delivered\n", tahvo_irq_name(irq_id), (int)irq_id);
++
+               ret = copy_to_user(buf + i * sizeof(irq_id), &irq_id,
+                                   sizeof(irq_id));
+               if (ret)