Make sure you have:
CONFIG_SND_MXC_PMIC=y
CONFIG_MXC_SPI_PMIC_CORE=y
CONFIG_MXC_PMIC=y
CONFIG_MXC_PMIC_CHARDEV=y
CONFIG_MXC_PMIC_MC13783=y
CONFIG_MXC_MC13783_AUDIO=y
set in your .config. Then apply the following patch (assuming 2.6.19.2 with Daniel's patches):
Index: linux-2.6.19.2-imx31/arch/arm/mach-mx3/mx31lite.c
===================================================================
--- linux-2.6.19.2-imx31/arch/arm/mach-mx3/mx31lite.c (revision 6782)
+++ linux-2.6.19.2-imx31/arch/arm/mach-mx3/mx31lite.c (revision 6783)
@@ -26,6 +26,7 @@
#include <linux/serial_8250.h>
#include <linux/input.h>
#include <linux/nodemask.h>
+#include <linux/spi/spi.h>
#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE)
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
@@ -242,7 +243,7 @@
#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE)
-static struct mtd_partition mxc_nand_partitions[4] = {
+static struct mtd_partition mxc_nand_partitions[] = {
{
.name = "nand.kernel",
.offset = MTDPART_OFS_APPEND,
@@ -281,6 +282,18 @@
}
#endif
+static struct spi_board_info mxc_spi_board_info[] __initdata = {
+ {
+ .modalias = "pmic_spi",
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+ .max_speed_hz = 4000000,
+ .bus_num = 2,
+ .chip_select = 0,
+ },
+};
+
+// TODO: #if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE)
+
/*!
* Board specific fixup function. It is called by \b setup_arch() in
* setup.c file very early on during kernel starts. It allows the user to
@@ -401,6 +414,10 @@
mxc_init_nor_mtd();
mxc_init_nand_mtd();
mxc_init_eth();
+
+ spi_register_board_info(mxc_spi_board_info,
+ ARRAY_SIZE(mxc_spi_board_info));
+
}
/*
I also made a bunch of changes for improved debugging and error checking:
Index: linux-2.6.19.2-imx31/arch/arm/mach-mx3/devices.c
===================================================================
--- linux-2.6.19.2-imx31/arch/arm/mach-mx3/devices.c (revision 6782)
+++ linux-2.6.19.2-imx31/arch/arm/mach-mx3/devices.c (revision 6783)
@@ -541,19 +541,23 @@
static inline void mxc_init_spi(void)
{
- /* SPBA configuration for CSPI2 - MCU is set */
- spba_take_ownership(SPBA_CSPI2, SPBA_MASTER_A);
#ifdef CONFIG_SPI_MXC_SELECT1
if (platform_device_register(&mxcspi1_device) < 0)
- printk("Error: Registering the SPI Controller_1\n");
+ printk(KERN_ERR "Error: Registering the SPI Controller_1\n");
#endif /* CONFIG_SPI_MXC_SELECT1 */
#ifdef CONFIG_SPI_MXC_SELECT2
+ /* SPBA configuration for CSPI2 - MCU is set
+ * note: only CSPI2 uses the SPBA???
+ */
+ if (spba_take_ownership(SPBA_CSPI2, SPBA_MASTER_A) < 0)
+ printk(KERN_ERR
+ "Error: Failed to take ownership of SPI Controller\n");
if (platform_device_register(&mxcspi2_device) < 0)
- printk("Error: Registering the SPI Controller_2\n");
+ printk(KERN_ERR "Error: Registering the SPI Controller_2\n");
#endif /* CONFIG_SPI_MXC_SELECT2 */
#ifdef CONFIG_SPI_MXC_SELECT3
if (platform_device_register(&mxcspi3_device) < 0)
- printk("Error: Registering the SPI Controller_3\n");
+ printk(KERN_ERR "Error: Registering the SPI Controller_3\n");
#endif /* CONFIG_SPI_MXC_SELECT3 */
}
#else
@@ -612,7 +616,9 @@
mxc_init_pcmcia();
/* SPBA configuration for SSI2 - SDMA and MCU are set */
- spba_take_ownership(SPBA_SSI2, SPBA_MASTER_C | SPBA_MASTER_A);
+ if (spba_take_ownership(SPBA_SSI2, SPBA_MASTER_C | SPBA_MASTER_A) < 0)
+ printk(KERN_ERR
+ "Error: Failed to take ownership of SSI Controller\n");
return 0;
}
Index: linux-2.6.19.2-imx31/drivers/mxc/pmic/core/mc13783.c
===================================================================
--- linux-2.6.19.2-imx31/drivers/mxc/pmic/core/mc13783.c (revision 6782)
+++ linux-2.6.19.2-imx31/drivers/mxc/pmic/core/mc13783.c (revision 6783)
@@ -64,12 +64,17 @@
unsigned int frame = 0;
int ret = 0;
- if (reg_num > MXC_PMIC_MAX_REG_NUM)
+ if (reg_num > MXC_PMIC_MAX_REG_NUM) {
+ printk(KERN_ERR "pmic_read: reg_num %u out of range\n", reg_num);
return PMIC_ERROR;
+ }
frame |= reg_num << MXC_PMIC_REG_NUM_SHIFT;
ret = spi_rw(pmic_drv_data.spi, (u8 *) & frame, 1);
+ if (ret) {
+ printk(KERN_ALERT "pmic_read: spi_rw failed: %d\n", ret);
+ }
*reg_val = frame & MXC_PMIC_FRAME_MASK;
@@ -151,7 +156,10 @@
int icid = 0;
ver->id = PMIC_MC13783;
- pmic_read(REG_REVISION, &rev_id);
+ if (pmic_read(REG_REVISION, &rev_id)) {
+ printk(KERN_NOTICE
+ "pmic_get_revision: pmic_read() failed\n");
+ }
rev1 = (rev_id & 0x018) >> 3;
rev2 = (rev_id & 0x007);
Index: linux-2.6.19.2-imx31/drivers/mxc/pmic/core/pmic.h
===================================================================
--- linux-2.6.19.2-imx31/drivers/mxc/pmic/core/pmic.h (revision 6782)
+++ linux-2.6.19.2-imx31/drivers/mxc/pmic/core/pmic.h (revision 6783)
@@ -58,11 +58,22 @@
.delay_usecs = 0,
};
struct spi_message m;
+ int rval;
spi_message_init(&m);
spi_message_add_tail(&t, &m);
- if (spi_sync(spi, &m) != 0 || m.status != 0)
+ rval = spi_sync(spi, &m);
+ if (unlikely(rval != 0)) {
+ printk(KERN_ALERT "pmic spi_rw: spi_sync returned %d\n", rval);
return PMIC_ERROR;
+ }
+ if (unlikely(m.status != 0)) {
+ printk(KERN_ALERT "pmic spi_rw: msg status %d, transferred %u\n",
+ m.status, m.actual_length);
+ return PMIC_ERROR;
+ }
+
+ dev_dbg(spi->dev, "pmic spi_rw: transferred %u, residual %d\n", m.actual_length, len-m.actual_length);
return (len - m.actual_length);
}
Index: linux-2.6.19.2-imx31/drivers/spi/spi.c
===================================================================
--- linux-2.6.19.2-imx31/drivers/spi/spi.c (revision 6782)
+++ linux-2.6.19.2-imx31/drivers/spi/spi.c (revision 6783)
@@ -484,6 +484,11 @@
complete(arg);
}
+inline static const char * safe_str(const char *str)
+{
+ return str ? str : "NULL";
+}
+
/**
* spi_sync - blocking/synchronous SPI data transfers
* @spi: device with which data will be exchanged
@@ -512,6 +517,12 @@
DECLARE_COMPLETION_ONSTACK(done);
int status;
+ pr_debug("spi_sync(): dev %s, master %s, transfer %p\n",
+ spi->dev.driver ? safe_str(spi->dev.driver->name) : "UNK",
+ spi->master->cdev.dev ?
+ safe_str(spi->master->cdev.dev->driver->name) : "UNK",
+ spi->master->transfer);
+
message->complete = spi_complete;
message->context = &done;
status = spi_async(spi, message);