From 649d2134287cdd4c31145e3d7bb41e401ae2222c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michael=20B=C3=BCsch?= Date: Sat, 21 Aug 2010 15:43:39 +0000 Subject: [PATCH] n810: Add retu/tahvo userspace interface debugging SVN-Revision: 22747 --- target/linux/omap24xx/config-2.6.35 | 4 +- .../510-retu-tahvo-user-debugging.patch | 324 ++++++++++++++++++ 2 files changed, 327 insertions(+), 1 deletion(-) create mode 100644 target/linux/omap24xx/patches-2.6.35/510-retu-tahvo-user-debugging.patch diff --git a/target/linux/omap24xx/config-2.6.35 b/target/linux/omap24xx/config-2.6.35 index e844ad80b4..92043b64d8 100644 --- a/target/linux/omap24xx/config-2.6.35 +++ b/target/linux/omap24xx/config-2.6.35 @@ -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 index 0000000000..0e4cd128dd --- /dev/null +++ b/target/linux/omap24xx/patches-2.6.35/510-retu-tahvo-user-debugging.patch @@ -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) -- 2.30.2