Browse files

Remainder of Bug Labs 2.0 base patchset

  • Loading branch information...
1 parent 493bd27 commit e881ca706021565e3e4221e8cdee324d6074e3fd Matt Isaacs committed Feb 16, 2010
Showing with 19,598 additions and 0 deletions.
  1. +494 −0 arch/arm/mach-omap2/board-omap3bug-dc-v4l.c
  2. +44 −0 arch/arm/mach-omap2/board-omap3bug-dc.h
  3. +194 −0 arch/arm/mach-omap2/board-omap3bug-flash.c
  4. +886 −0 arch/arm/mach-omap2/board-omap3bug.c
  5. +81 −0 arch/arm/mach-omap2/twl4030-generic-scripts.c
  6. +13 −0 arch/arm/mach-omap2/twl4030-generic-scripts.h
  7. +17 −0 drivers/bmi/Kconfig
  8. +8 −0 drivers/bmi/Makefile
  9. +7 −0 drivers/bmi/core/Makefile
  10. +319 −0 drivers/bmi/core/core.c
  11. +35 −0 drivers/bmi/core/device.c
  12. +27 −0 drivers/bmi/core/driver.c
  13. +32 −0 drivers/bmi/core/eeprom.c
  14. +472 −0 drivers/bmi/core/slot.c
  15. +105 −0 drivers/bmi/pims/Kconfig
  16. +17 −0 drivers/bmi/pims/Makefile
  17. +23 −0 drivers/bmi/pims/camera/Kconfig
  18. +12 −0 drivers/bmi/pims/camera/Makefile
  19. +929 −0 drivers/bmi/pims/camera/bmi_ov2640.c
  20. +915 −0 drivers/bmi/pims/camera/bmi_vs6624.c
  21. +611 −0 drivers/bmi/pims/camera/bug_camera.c
  22. +72 −0 drivers/bmi/pims/camera/bug_camera.h
  23. +301 −0 drivers/bmi/pims/camera/ov2640.c
  24. +14 −0 drivers/bmi/pims/camera/ov2640.h
  25. +597 −0 drivers/bmi/pims/camera/vs6624_access.c
  26. +17 −0 drivers/bmi/pims/camera/vs6624_access.h
  27. +373 −0 drivers/bmi/pims/camera/vs6624_patch.c
  28. +467 −0 drivers/bmi/pims/camera/vs6624_regs.h
  29. +6 −0 drivers/bmi/pims/factory_test/Makefile
  30. +952 −0 drivers/bmi/pims/factory_test/factory_test.c
  31. +6 −0 drivers/bmi/pims/gps/Makefile
  32. +468 −0 drivers/bmi/pims/gps/bmi_gps.c
  33. +6 −0 drivers/bmi/pims/gsm/Makefile
  34. +301 −0 drivers/bmi/pims/gsm/bmi_gsm.c
  35. +9 −0 drivers/bmi/pims/lcd/Makefile
  36. +114 −0 drivers/bmi/pims/lcd/acc.c
  37. +35 −0 drivers/bmi/pims/lcd/acc.h
  38. +1,790 −0 drivers/bmi/pims/lcd/bmi_lcd.c
  39. +1,775 −0 drivers/bmi/pims/lcd/bmi_lcd_inf.c
  40. +1,855 −0 drivers/bmi/pims/lcd/bmi_lcd_mi.c
  41. +632 −0 drivers/bmi/pims/lcd/bmi_s320x240.c
  42. +421 −0 drivers/bmi/pims/lcd/lcd_ctl.c
  43. +87 −0 drivers/bmi/pims/lcd/lcd_ctl.h
  44. +6 −0 drivers/bmi/pims/mdacc/Kconfig
  45. +9 −0 drivers/bmi/pims/mdacc/Makefile
  46. +381 −0 drivers/bmi/pims/mdacc/acc.c
  47. +54 −0 drivers/bmi/pims/mdacc/acc.h
  48. +511 −0 drivers/bmi/pims/mdacc/avr.c
  49. +54 −0 drivers/bmi/pims/mdacc/avr.h
  50. +150 −0 drivers/bmi/pims/mdacc/cque.c
  51. +42 −0 drivers/bmi/pims/mdacc/cque.h
  52. +176 −0 drivers/bmi/pims/mdacc/ctl.c
  53. +43 −0 drivers/bmi/pims/mdacc/ctl.h
  54. +333 −0 drivers/bmi/pims/mdacc/md.c
  55. +60 −0 drivers/bmi/pims/mdacc/md.h
  56. +333 −0 drivers/bmi/pims/mdacc/mdacc.c
  57. +43 −0 drivers/bmi/pims/mdacc/mdacc.h
  58. +474 −0 drivers/bmi/pims/mdacc/mon.c
  59. +61 −0 drivers/bmi/pims/mdacc/mon.h
  60. +7 −0 drivers/bmi/pims/projector/Makefile
  61. +674 −0 drivers/bmi/pims/projector/bmi_projector.c
  62. +476 −0 drivers/bmi/pims/projector/ch7024.c
  63. +166 −0 drivers/bmi/pims/projector/ch7024.h
  64. +6 −0 drivers/bmi/pims/sensor/Makefile
Sorry, we could not display the entire diff because it was too big.
View
494 arch/arm/mach-omap2/board-omap3bug-dc-v4l.c
@@ -0,0 +1,494 @@
+/*
+ * arch/arm/mach-omap2/board-omap3evm-dc-v4l.c
+ *
+ * Driver for OMAP3 EVM Mass Market Daughter Card
+ *
+ * Copyright (C) 2008 Texas Instruments Inc
+ * Author: Vaibhav Hiremath <hvaibhav@ti.com>
+ *
+ * Contributors:
+ * Anuj Aggarwal <anuj.aggarwal@ti.com>
+ * Sivaraj R <sivaraj@ti.com>
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/videodev2.h>
+#include <linux/i2c/twl4030.h>
+
+#include <mach/mux.h>
+
+#include <media/v4l2-int-device.h>
+#include <media/tvp514x.h>
+
+/* Include V4L2 ISP-Camera driver related header file */
+#include <../drivers/media/video/omap34xxcam.h>
+#include <../drivers/media/video/isp/ispreg.h>
+
+#include "board-omap3bug-dc.h"
+
+#define MODULE_NAME "omap3evmdc"
+
+/* Is decoder present on-board or Daughter card */
+static int is_dec_onboard;
+
+/* GPIO pins Daughter Card */
+#define GPIO134_SEL_TVP_Y (134)
+#define GPIO54_SEL_EXP_CAM (54)
+#define GPIO136_SEL_CAM (136)
+/* GPIO pins for GEN_2 EVM */
+#define GPIO98_VID_DEC_RES (98)
+#define nCAM_VD_SEL (157)
+
+#if defined(CONFIG_VIDEO_TVP514X) || defined(CONFIG_VIDEO_TVP514X_MODULE)
+#if defined(CONFIG_VIDEO_OMAP3_CAM) || defined(CONFIG_VIDEO_OMAP3_CAM_MODULE)
+static struct omap34xxcam_hw_config decoder_hwc = {
+ .dev_index = 0,
+ .dev_minor = 0,
+ .dev_type = OMAP34XXCAM_SLAVE_SENSOR,
+ .u.sensor.xclk = OMAP34XXCAM_XCLK_NONE,
+ .u.sensor.sensor_isp = 1,
+};
+
+static struct isp_interface_config tvp5146_if_config = {
+ .ccdc_par_ser = ISP_PARLL_YUV_BT,
+ .dataline_shift = 0x1,
+ .hsvs_syncdetect = ISPCTRL_SYNC_DETECT_VSRISE,
+ .strobe = 0x0,
+ .prestrobe = 0x0,
+ .shutter = 0x0,
+ .u.par.par_bridge = 0x0,
+ .u.par.par_clk_pol = 0x0,
+};
+#endif
+
+static struct v4l2_ifparm ifparm = {
+ .if_type = V4L2_IF_TYPE_BT656,
+ .u = {
+ .bt656 = {
+ .frame_start_on_rising_vs = 1,
+ .bt_sync_correct = 0,
+ .swap = 0,
+ .latch_clk_inv = 0,
+ .nobt_hs_inv = 0, /* active high */
+ .nobt_vs_inv = 0, /* active high */
+ .mode = V4L2_IF_TYPE_BT656_MODE_BT_8BIT,
+ .clock_min = TVP514X_XCLK_BT656,
+ .clock_max = TVP514X_XCLK_BT656,
+ },
+ },
+};
+
+/**
+ * @brief tvp5146_ifparm - Returns the TVP5146 decoder interface parameters
+ *
+ * @param p - pointer to v4l2_ifparm structure
+ *
+ * @return result of operation - 0 is success
+ */
+static int tvp5146_ifparm(struct v4l2_ifparm *p)
+{
+ if (p == NULL)
+ return -EINVAL;
+
+ *p = ifparm;
+ return 0;
+}
+
+/**
+ * @brief tvp5146_set_prv_data - Returns tvp5146 omap34xx driver private data
+ *
+ * @param priv - pointer to omap34xxcam_hw_config structure
+ *
+ * @return result of operation - 0 is success
+ */
+static int tvp5146_set_prv_data(void *priv)
+{
+#if defined(CONFIG_VIDEO_OMAP3_CAM) || defined(CONFIG_VIDEO_OMAP3_CAM_MODULE)
+ struct omap34xxcam_hw_config *hwc = priv;
+
+ if (priv == NULL)
+ return -EINVAL;
+
+ hwc->u.sensor.sensor_isp = decoder_hwc.u.sensor.sensor_isp;
+ hwc->u.sensor.xclk = decoder_hwc.u.sensor.xclk;
+ hwc->dev_index = decoder_hwc.dev_index;
+ hwc->dev_minor = decoder_hwc.dev_minor;
+ hwc->dev_type = decoder_hwc.dev_type;
+ return 0;
+#else
+ return -EINVAL;
+#endif
+}
+
+/**
+ * @brief omap3evmdc_set_mux - Sets mux to enable/disable signal routing to
+ * different peripherals present in board
+ * IMPORTANT - This function will take care of writing appropriate values for
+ * active low signals as well
+ *
+ * @param mux_id - enum, mux id to enable/disable
+ * @param value - enum, ENABLE_MUX for enabling and DISABLE_MUX for disabling
+ *
+ * @return result of operation - 0 is success
+ */
+static int omap3evmdc_set_mux(enum omap3evmdc_mux mux_id, enum config_mux value)
+{
+ int err = 0;
+
+ if (unlikely(mux_id >= NUM_MUX)) {
+ printk(KERN_ERR MODULE_NAME ": Invalid mux id\n");
+ return -EPERM;
+ }
+
+ switch (mux_id) {
+ case MUX_TVP5146:
+ if (ENABLE_MUX == value) {
+ /* Enable TVP5146 Video in (GPIO134 = 0) */
+ gpio_set_value(GPIO134_SEL_TVP_Y, 0);
+ /* Disable Expansion Camera Video in (GPIO54 = 1) */
+ gpio_set_value(GPIO54_SEL_EXP_CAM, 1);
+ /* Disable Camera Video in (GPIO136 = 1)*/
+ gpio_set_value(GPIO136_SEL_CAM, 1);
+ } else {
+ /* Disable TVP5146 Video in (GPIO134 = 0) */
+ gpio_set_value(GPIO134_SEL_TVP_Y, 1);
+ }
+ break;
+
+ case MUX_CAMERA_SENSOR:
+ if (ENABLE_MUX == value) {
+ /* Disable TVP5146 Video in (GPIO134 = 0) */
+ gpio_set_value(GPIO134_SEL_TVP_Y, 1);
+ /* Disable Exapansion Camera Video in (GPIO54 = 1) */
+ gpio_set_value(GPIO54_SEL_EXP_CAM, 1);
+ /* Enable Camera Video in (GPIO136 = 1) */
+ gpio_set_value(GPIO136_SEL_CAM, 0);
+ } else {
+ /* Disable Camera Video in (GPIO136 = 1) */
+ gpio_set_value(GPIO136_SEL_CAM, 1);
+ }
+ break;
+
+ case MUX_EXP_CAMERA_SENSOR:
+ if (ENABLE_MUX == value) {
+ /* Disable TVP5146 Video in (GPIO134 = 0) */
+ gpio_set_value(GPIO134_SEL_TVP_Y, 1);
+ /* Enable Expansion Camera Video in (GPIO54 = 1) */
+ gpio_set_value(GPIO54_SEL_EXP_CAM, 0);
+ /* Disable Camera Video in (GPIO136 = 1) */
+ gpio_set_value(GPIO136_SEL_CAM, 1);
+ } else {
+ /* Disable Expansion Camera Video in (GPIO54 = 1) */
+ gpio_set_value(GPIO54_SEL_EXP_CAM, 1);
+ }
+ break;
+
+ case NUM_MUX:
+ default:
+ printk(KERN_ERR "Invalid mux id\n");
+ err = -EPERM;
+ }
+
+ return err;
+}
+
+/**
+ * @brief omap3evm_set_mux - Sets mux to enable/disable signal routing to
+ * different peripherals present on new EVM board
+ * IMPORTANT - This function will take care of writing appropriate values for
+ * active low signals as well
+ *
+ * @param mux_id - enum, mux id to enable/disable
+ * @param value - enum, ENABLE_MUX for enabling and DISABLE_MUX for disabling
+ *
+ * @return result of operation - 0 is success
+ */
+static int omap3evm_set_mux(enum omap3evmdc_mux mux_id, enum config_mux value)
+{
+ unsigned char val;
+ int err = 0;
+
+ if (unlikely(mux_id >= NUM_MUX)) {
+ printk(KERN_ERR MODULE_NAME ": Invalid mux id\n");
+ return -EPERM;
+ }
+
+ /*FIXME: Need to follow standard GPIO API's to control
+ * TWL4030 GPIO.
+ */
+ /* Enable TWL GPIO Module */
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0x04, REG_GPIO_CTRL);
+
+ /* Configure GPIO2 and GPIO6 as output */
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val, REG_GPIODATADIR1);
+ val |= 0x44;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val, REG_GPIODATADIR1);
+
+ /* Configure GPIO8 as output*/
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val, REG_GPIODATADIR2);
+ val |= 0x1;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val, REG_GPIODATADIR2);
+
+ /* Set GPIO pull-up */
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val, REG_GPIOPUPDCTR1);
+ val |= 0x20;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val, REG_GPIOPUPDCTR1);
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val, REG_GPIOPUPDCTR3);
+ val |= 0x2;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val, REG_GPIOPUPDCTR3);
+
+ /* Set GPIO6 = 1 */
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val, REG_GPIODATAOUT1);
+ val |= 0x40;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val, REG_GPIODATAOUT1);
+
+ switch (mux_id) {
+ case MUX_TVP5146:
+ if (ENABLE_MUX == value) {
+ /* Set GPIO8 = 0 */
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
+ REG_GPIODATAOUT2);
+ val &= ~0x1;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
+ REG_GPIODATAOUT2);
+
+ gpio_set_value(nCAM_VD_SEL, 1);
+ } else {
+ /* Set GPIO8 = 0 */
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
+ REG_GPIODATAOUT2);
+ val |= 0x1;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
+ REG_GPIODATAOUT2);
+ }
+ break;
+
+ case MUX_CAMERA_SENSOR:
+ if (ENABLE_MUX == value) {
+ /* Set GPIO8 = 0 */
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
+ REG_GPIODATAOUT2);
+ val &= ~0x1;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
+ REG_GPIODATAOUT2);
+
+ gpio_set_value(nCAM_VD_SEL, 0);
+ } else {
+ /* Set GPIO8 = 0 */
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
+ REG_GPIODATAOUT2);
+ val |= 0x1;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
+ REG_GPIODATAOUT2);
+ }
+ break;
+
+ case MUX_EXP_CAMERA_SENSOR:
+ if (ENABLE_MUX == value) {
+ /* Set GPIO8 = 1 */
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
+ REG_GPIODATAOUT2);
+ val |= 0x1;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
+ REG_GPIODATAOUT2);
+
+ } else {
+ /* Set GPIO8 = 0 */
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
+ REG_GPIODATAOUT2);
+ val &= ~0x1;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
+ REG_GPIODATAOUT2);
+ }
+ break;
+
+ case NUM_MUX:
+ default:
+ printk(KERN_ERR "Invalid mux id\n");
+ err = -EPERM;
+ }
+
+ return err;
+}
+/**
+ * @brief tvp5146_power_set - Power-on or power-off TVP5146 device
+ *
+ * @param power - enum, Power on/off, resume/standby
+ *
+ * @return result of operation - 0 is success
+ */
+static int tvp5146_power_set(enum v4l2_power power)
+{
+ switch (power) {
+ case V4L2_POWER_OFF:
+ /* Disable mux for TVP5146 decoder data path */
+ if (is_dec_onboard) {
+ if (omap3evm_set_mux(MUX_TVP5146, DISABLE_MUX))
+ return -ENODEV;
+ } else {
+ if (omap3evmdc_set_mux(MUX_TVP5146, DISABLE_MUX))
+ return -ENODEV;
+ }
+ break;
+
+ case V4L2_POWER_STANDBY:
+ break;
+
+ case V4L2_POWER_ON:
+ /* Enable mux for TVP5146 decoder data path */
+ if (is_dec_onboard) {
+ if (omap3evm_set_mux(MUX_TVP5146, ENABLE_MUX))
+ return -ENODEV;
+ } else {
+ if (omap3evmdc_set_mux(MUX_TVP5146, ENABLE_MUX))
+ return -ENODEV;
+ }
+
+#if defined(CONFIG_VIDEO_OMAP3_CAM) || defined(CONFIG_VIDEO_OMAP3_CAM_MODULE)
+ isp_configure_interface(&tvp5146_if_config);
+#endif
+ break;
+
+ default:
+ return -ENODEV;
+ break;
+ }
+ return 0;
+}
+
+static struct tvp514x_platform_data tvp5146_pdata = {
+ .master = "omap34xxcam",
+ .power_set = tvp5146_power_set,
+ .priv_data_set = tvp5146_set_prv_data,
+ .ifparm = tvp5146_ifparm,
+ /* Some interface dependent params */
+ .clk_polarity = 0, /* data clocked out on falling edge */
+ .hs_polarity = 1, /* 0 - Active low, 1- Active high */
+ .vs_polarity = 1, /* 0 - Active low, 1- Active high */
+};
+
+static struct i2c_board_info __initdata tvp5146_i2c_board_info = {
+ I2C_BOARD_INFO("tvp5146m2", 0),
+ .platform_data = &tvp5146_pdata,
+};
+
+#endif /* #ifdef CONFIG_VIDEO_TVP514X */
+
+/**
+ * @brief omap3evmdc_mdc_config - GPIO configuration for
+ * GPIO 134, 54 and 136
+ *
+ * @return result of operation - 0 is success
+ */
+static int omap3evmdc_mdc_config(void)
+{
+ if (is_dec_onboard) {
+ unsigned char val;
+
+ /* Set GPIO8 = 1 */
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
+ REG_GPIODATAOUT2);
+ val &= ~0x1;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
+ REG_GPIODATAOUT2);
+
+ /* Enable Video Decoder */
+ omap_cfg_reg(AA21_34XX_GPIO157);
+ if (gpio_request(nCAM_VD_SEL, "Vid-Dec Sel") < 0) {
+ printk(KERN_ERR "Failed to get GPIO 157\n");
+ return -EINVAL;
+ }
+ gpio_direction_output(nCAM_VD_SEL, 1);
+
+ omap_cfg_reg(C23_34XX_GPIO98);
+ if (gpio_request(GPIO98_VID_DEC_RES, "vid-dec reset") < 0) {
+ printk(KERN_ERR "failed to get GPIO98_VID_DEC_RES\n");
+ return -EINVAL;
+ }
+ gpio_direction_output(GPIO98_VID_DEC_RES, 1);
+ } else {
+
+ /* Setting the MUX configuration */
+ omap_cfg_reg(AG4_34XX_GPIO134);
+ omap_cfg_reg(U8_34XX_GPIO54);
+ omap_cfg_reg(AE4_34XX_GPIO136);
+
+ if (gpio_request(GPIO134_SEL_TVP_Y, "TVP5146 Vid-in") < 0) {
+ printk(KERN_ERR MODULE_NAME ": Can't get GPIO 134\n");
+ return -EINVAL;
+ }
+
+ if (gpio_request(GPIO54_SEL_EXP_CAM, "EXP_CAM Vid-in") < 0) {
+ printk(KERN_ERR MODULE_NAME ": Can't get GPIO 54\n");
+ return -EINVAL;
+ }
+
+ if (gpio_request(GPIO136_SEL_CAM, "CAM Vid-in") < 0) {
+ printk(KERN_ERR MODULE_NAME ": Can't get GPIO 136\n");
+ return -EINVAL;
+ }
+
+ /* Make GPIO as output */
+ gpio_direction_output(GPIO134_SEL_TVP_Y, 0);
+ gpio_direction_output(GPIO54_SEL_EXP_CAM, 0);
+ gpio_direction_output(GPIO136_SEL_CAM, 0);
+ }
+
+ return 0;
+}
+
+/**
+ * @brief omap3evmdc_init - module init function. Should be called before any
+ * client driver init call
+ *
+ * @return result of operation - 0 is success
+ */
+int __init omap3evmdc_init(int is_onboard, int dec_i2c_bus, int dec_i2c_id)
+{
+ int err;
+
+ /* Status of Video Decoder : On Board or DC */
+ is_dec_onboard = is_onboard;
+
+ err = omap3evmdc_mdc_config();
+ if (err) {
+ printk(KERN_ERR MODULE_NAME ": MDC configuration failed \n");
+ return err;
+ }
+
+ /*
+ * Register the I2C devices present in the board to the I2C
+ * framework.
+ * If more I2C devices are added, then each device information should
+ * be registered with I2C using i2c_register_board_info().
+ */
+#if defined(CONFIG_VIDEO_TVP514X) || defined(CONFIG_VIDEO_TVP514X_MODULE)
+ tvp5146_i2c_board_info.addr = dec_i2c_id;
+ err = i2c_register_board_info(dec_i2c_bus,
+ &tvp5146_i2c_board_info, 1);
+ if (err) {
+ printk(KERN_ERR MODULE_NAME \
+ ": TVP5146 I2C Board Registration failed \n");
+ return err;
+ }
+#endif
+ printk(KERN_INFO MODULE_NAME ": Driver registration complete \n");
+
+ return 0;
+}
View
44 arch/arm/mach-omap2/board-omap3bug-dc.h
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/mach-omap2/board-omap3evm-dc.h
+ *
+ * Copyright (C) 2008 Texas Instruments Inc
+ * Author: Vaibhav Hiremath <hvaibhav@ti.com>
+ *
+ * Contributors:
+ * Anuj Aggarwal <anuj.aggarwal@ti.com>
+ * Sivaraj R <sivaraj@ti.com>
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __BOARD_OMAP3EVM_DC_H_
+#define __BOARD_OMAP3EVM_DC_H_
+
+/* mux id to enable/disable signal routing to different peripherals */
+enum omap3evmdc_mux {
+ MUX_TVP5146 = 0,
+ MUX_CAMERA_SENSOR,
+ MUX_EXP_CAMERA_SENSOR,
+ NUM_MUX
+};
+
+/* enum to enable or disable mux */
+enum config_mux {
+ DISABLE_MUX,
+ ENABLE_MUX
+};
+
+int omap3evmdc_init(int dec_sts, int dec_i2c_bus, int dec_i2c_id);
+#endif /* __BOARD_OMAP3EVM_DC_H_ */
View
194 arch/arm/mach-omap2/board-omap3bug-flash.c
@@ -0,0 +1,194 @@
+/*
+ * board-omap3bug-flash.c
+ *
+ * Copyright (c) 2008 Texas Instruments,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/onenand_regs.h>
+#include <linux/types.h>
+#include <linux/io.h>
+
+#include <asm/mach/flash.h>
+#include <mach/onenand.h>
+#include <mach/board.h>
+#include <mach/gpmc.h>
+#include <mach/nand.h>
+
+#define ONENAND_MAP 0x20000000
+#define GPMC_CS0_BASE 0x60
+#define GPMC_CS_SIZE 0x30
+
+static int omap3bug_onenand_setup(void __iomem *, int freq);
+
+static struct mtd_partition omap3bug_onenand_partitions[] = {
+ {
+ .name = "xloader-onenand",
+ .offset = 0,
+ .size = 4*(64*2048),
+ .mask_flags = MTD_WRITEABLE
+ },
+ {
+ .name = "uboot-onenand",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 15*(64*2048),
+ .mask_flags = MTD_WRITEABLE
+ },
+ {
+ .name = "params-onenand",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1*(64*2048),
+ },
+ {
+ .name = "linux-onenand",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 40*(64*2048),
+ },
+ {
+ .name = "jffs2-onenand",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_onenand_platform_data omap3bug_onenand_data = {
+ .parts = omap3bug_onenand_partitions,
+ .nr_parts = ARRAY_SIZE(omap3bug_onenand_partitions),
+ .onenand_setup = omap3bug_onenand_setup,
+ .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */
+};
+
+static struct platform_device omap3bug_onenand_device = {
+ .name = "omap2-onenand",
+ .id = -1,
+ .dev = {
+ .platform_data = &omap3bug_onenand_data,
+ },
+};
+
+static struct mtd_partition omap3bug_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "xloader-nand",
+ .offset = 0,
+ .size = 4*(128 * 1024),
+ .mask_flags = MTD_WRITEABLE
+ },
+ {
+ .name = "uboot-nand",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 14*(128 * 1024),
+ .mask_flags = MTD_WRITEABLE
+ },
+ {
+ .name = "params-nand",
+
+ .offset = MTDPART_OFS_APPEND,
+ .size = 2*(128 * 1024)
+ },
+ {
+ .name = "linux-nand",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 40*(128 * 1024)
+ },
+ {
+ .name = "jffs2-nand",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ },
+};
+
+static struct omap_nand_platform_data omap3bug_nand_data = {
+ .parts = omap3bug_nand_partitions,
+ .nr_parts = ARRAY_SIZE(omap3bug_nand_partitions),
+ .nand_setup = NULL,
+ .dma_channel = -1, /* disable DMA in OMAP NAND driver */
+ .dev_ready = NULL,
+};
+
+static struct resource omap3bug_nand_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device omap3bug_nand_device = {
+ .name = "omap2-nand",
+ .id = 0,
+ .dev = {
+ .platform_data = &omap3bug_nand_data,
+ },
+ .num_resources = 1,
+ .resource = &omap3bug_nand_resource,
+};
+
+/*
+ * omap3bug_onenand_setup - Set the onenand sync mode
+ * @onenand_base: The onenand base address in GPMC memory map
+ *
+ */
+
+static int omap3bug_onenand_setup(void __iomem *onenand_base, int freq)
+{
+ /* nothing is required to be setup for onenand as of now */
+ return 0;
+}
+
+void __init omap3bug_flash_init(void)
+{
+ u8 cs = 0;
+ u8 onenandcs = GPMC_CS_NUM + 1, nandcs = GPMC_CS_NUM + 1;
+ u32 gpmc_base_add = OMAP34XX_GPMC_VIRT;
+
+ while (cs < GPMC_CS_NUM) {
+ u32 ret = 0;
+ ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+ /*
+ * xloader/Uboot would have programmed the NAND/oneNAND
+ * base address for us This is a ugly hack. The proper
+ * way of doing this is to pass the setup of u-boot up
+ * to kernel using kernel params - something on the
+ * lines of machineID. Check if NAND/oneNAND is configured
+ */
+ if ((ret & 0xC00) == 0x800) {
+ /* Found it!! */
+ if (nandcs > GPMC_CS_NUM)
+ nandcs = cs;
+ } else {
+ ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
+ if ((ret & 0x3F) == (ONENAND_MAP >> 24))
+ onenandcs = cs;
+ }
+ cs++;
+ }
+ if ((nandcs > GPMC_CS_NUM) && (onenandcs > GPMC_CS_NUM)) {
+ printk(KERN_INFO "NAND/OneNAND: Unable to find configuration "
+ " in GPMC\n ");
+ return;
+ }
+
+ if (nandcs < GPMC_CS_NUM) {
+ omap3bug_nand_data.cs = nandcs;
+ omap3bug_nand_data.gpmc_cs_baseaddr = (void *)(gpmc_base_add +
+ GPMC_CS0_BASE + nandcs*GPMC_CS_SIZE);
+ omap3bug_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add);
+
+ if (platform_device_register(&omap3bug_nand_device) < 0) {
+ printk(KERN_ERR "Unable to register NAND device\n");
+ }
+ }
+
+ if (onenandcs < GPMC_CS_NUM) {
+ omap3bug_onenand_data.cs = onenandcs;
+ if (platform_device_register(&omap3bug_onenand_device) < 0)
+ printk(KERN_ERR "Unable to register OneNAND device\n");
+ }
+}
+
View
886 arch/arm/mach-omap2/board-omap3bug.c
@@ -0,0 +1,886 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3bug.c
+ *
+ * Copyright (C) 2008 Texas Instruments
+ *
+ * Modified from mach-omap2/board-3430sdp.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/input.h>
+#include <linux/leds.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+#include <linux/spi/sc16is7x.h>
+#include <linux/i2c.h>
+#include <linux/i2c/twl4030.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/mmc/host.h>
+#include <linux/bmi/omap_bmi.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/gpio.h>
+#include <mach/keypad.h>
+#include <mach/board.h>
+#include <mach/usb.h>
+#include <mach/common.h>
+#include <mach/mcspi.h>
+#include <mach/mux.h>
+//#include <mach/display.h>
+//#include <mach/pm.h>
+#include <mach/clock.h>
+
+#include "sdram-micron-mt46h32m32lf-6.h"
+#include "twl4030-generic-scripts.h"
+#include "mmc-twl4030.h"
+//#include "pm.h"
+//#include "omap3-opp.h"
+#include "board-omap3bug-dc.h"
+#include <linux/regulator/machine.h>
+
+#define OMAP3_BUG_TS_GPIO 175
+
+extern void omap3bug_flash_init(void);
+
+static int omap3bug_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio);
+
+static int omap3bug_ioexp_gpio_setup(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio, void *context);
+static int omap3bug_ioexp_gpio_teardown(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio, void *context);
+
+static int omap3bug_spi_uart_gpio_setup(struct spi_device *spi,
+ unsigned gpio, unsigned ngpio, void *context);
+
+/*
+static struct omap_uart_config omap3_bug_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+*/
+
+static struct regulator_consumer_supply bug_vmmc1_supply = {
+ .supply = "vmmc",
+};
+
+static struct regulator_consumer_supply bug_vaux2_supply = {
+ .supply = "vaux2",
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data bug_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &bug_vmmc1_supply,
+};
+
+/* VAUX2 for USB PHY (max 100 mA) */
+static struct regulator_init_data bug_vaux2 = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .boot_on = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &bug_vaux2_supply,
+};
+
+static struct twl4030_gpio_platform_data omap3bug_gpio_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES,
+ .irq_base = TWL4030_GPIO_IRQ_BASE,
+ .irq_end = TWL4030_GPIO_IRQ_END,
+ .pulldowns = BIT(2) | BIT(6) | BIT(8) | BIT(13)
+ | BIT(16) | BIT(17),
+ .setup = omap3bug_twl_gpio_setup,
+
+};
+
+static struct twl4030_usb_data omap3bug_usb_data = {
+ .usb_mode = T2_USB_MODE_ULPI,
+};
+
+
+static struct twl4030_madc_platform_data omap3bug_madc_data = {
+ .irq_line = 1,
+};
+
+static struct twl4030_platform_data omap3bug_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
+
+ /* platform_data for children goes here */
+ // .keypad = &omap3bug_kp_data,
+ .madc = &omap3bug_madc_data,
+ .usb = &omap3bug_usb_data,
+ //.power = GENERIC3430_T2SCRIPTS_DATA,
+ .vmmc1 = &bug_vmmc1,
+ .vaux2 = &bug_vaux2,
+ .gpio = &omap3bug_gpio_data,
+};
+
+static struct sc16is7x_platform_data omap3bug_spi_uart_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES + TWL4030_GPIO_MAX+16,
+ .setup = omap3bug_spi_uart_gpio_setup,
+ /* .teardown = omap3bug_ioexp_gpio_teardown,*/
+};
+
+static struct spi_board_info __initdata omap3bug_spi_board_info[] = {
+ {
+ .modalias = "sc16is7x",
+ .bus_num = 1,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ .max_speed_hz = 2000000,
+ .platform_data = &omap3bug_spi_uart_data,
+ },
+};
+
+static struct pca953x_platform_data omap3bug_ioexp_data = {
+ .gpio_base = OMAP_MAX_GPIO_LINES + TWL4030_GPIO_MAX,
+ .setup = omap3bug_ioexp_gpio_setup,
+ .teardown = omap3bug_ioexp_gpio_teardown,
+};
+
+static struct i2c_board_info __initdata omap3bug_i2c1_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("tps65930", 0x48),
+ .flags = I2C_CLIENT_WAKE,
+ .irq = INT_34XX_SYS_NIRQ,
+ .platform_data = &omap3bug_twldata,
+ },
+};
+
+static struct i2c_board_info __initdata omap3bug_i2c2_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("pca9555", 0x20),
+ //.irq = gpio_to_irq(63),
+ .platform_data = &omap3bug_ioexp_data,
+ },
+};
+
+static struct i2c_board_info __initdata omap3bug_i2c3_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("pca9546", 0x70),
+ },
+};
+
+static int __init omap3_bug_i2c_init(void)
+{
+ omap_register_i2c_bus(1, 2600, omap3bug_i2c1_boardinfo,
+ ARRAY_SIZE(omap3bug_i2c1_boardinfo));
+ omap_register_i2c_bus(2, 400, omap3bug_i2c2_boardinfo,
+ ARRAY_SIZE(omap3bug_i2c2_boardinfo));
+ omap_register_i2c_bus(3, 100, omap3bug_i2c3_boardinfo,
+ ARRAY_SIZE(omap3bug_i2c2_boardinfo));
+ return 0;
+}
+/*
+ * For new frame buffer driver based on DSS2 library
+ */
+#ifdef CONFIG_OMAP2_DSS
+
+#ifdef CONFIG_FB_OMAP2
+static struct resource omap3bug_vout_resource[3 - CONFIG_FB_OMAP2_NUM_FBS] = {
+};
+#else /* CONFIG_FB_OMAP2 */
+static struct resource omap3bug_vout_resource[2] = {
+};
+#endif /* CONFIG_FB_OMAP2 */
+static struct platform_device omap3bug_vout_device = {
+ .name = "omap_vout",
+ .num_resources = ARRAY_SIZE(omap3bug_vout_resource),
+ .resource = &omap3bug_vout_resource[0],
+ .id = -1,
+};
+
+#define LCD_PANEL_LR 2
+#define LCD_PANEL_UD 3
+#define LCD_PANEL_INI 152
+#define LCD_PANEL_ENABLE_GPIO 153
+#define LCD_PANEL_QVGA 154
+#define LCD_PANEL_RESB 155
+
+#define ENABLE_VDAC_DEDICATED 0x03
+#define ENABLE_VDAC_DEV_GRP 0x20
+#define ENABLE_VPLL2_DEDICATED 0x05
+#define ENABLE_VPLL2_DEV_GRP 0xE0
+
+static int lcd_enabled;
+static int dvi_enabled;
+
+static void __init omap3_bug_display_init(void)
+{
+ int r;
+ r = gpio_request(LCD_PANEL_LR, "lcd_panel_lr");
+ if (r) {
+ printk(KERN_ERR "failed to get LCD_PANEL_LR\n");
+ return;
+ }
+ r = gpio_request(LCD_PANEL_UD, "lcd_panel_ud");
+ if (r) {
+ printk(KERN_ERR "failed to get LCD_PANEL_UD\n");
+ goto err_1;
+ }
+
+ r = gpio_request(LCD_PANEL_INI, "lcd_panel_ini");
+ if (r) {
+ printk(KERN_ERR "failed to get LCD_PANEL_INI\n");
+ goto err_2;
+ }
+ r = gpio_request(LCD_PANEL_RESB, "lcd_panel_resb");
+ if (r) {
+ printk(KERN_ERR "failed to get LCD_PANEL_RESB\n");
+ goto err_3;
+ }
+ r = gpio_request(LCD_PANEL_QVGA, "lcd_panel_qvga");
+ if (r) {
+ printk(KERN_ERR "failed to get LCD_PANEL_QVGA\n");
+ goto err_4;
+ }
+
+ gpio_direction_output(LCD_PANEL_RESB, 1);
+ gpio_direction_output(LCD_PANEL_INI, 1);
+ gpio_direction_output(LCD_PANEL_QVGA, 0);
+ gpio_direction_output(LCD_PANEL_LR, 1);
+ gpio_direction_output(LCD_PANEL_UD, 1);
+
+ return;
+
+err_4:
+ gpio_free(LCD_PANEL_RESB);
+err_3:
+ gpio_free(LCD_PANEL_INI);
+err_2:
+ gpio_free(LCD_PANEL_UD);
+err_1:
+ gpio_free(LCD_PANEL_LR);
+
+}
+
+static int omap3_bug_panel_enable_lcd(struct omap_display *display)
+{
+ if (dvi_enabled) {
+ return -EINVAL;
+ }
+ if (omap_rev() > OMAP3430_REV_ES1_0) {
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+ ENABLE_VPLL2_DEDICATED, TWL4030_PLL2_DEDICATED);
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+ ENABLE_VPLL2_DEV_GRP, TWL4030_VPLL2_DEV_GRP);
+ }
+ gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
+ lcd_enabled = 1;
+ return 0;
+}
+
+static void omap3_bug_panel_disable_lcd(struct omap_display *display)
+{
+ if (omap_rev() > OMAP3430_REV_ES1_0) {
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x0,
+ TWL4030_PLL2_DEDICATED);
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x0,
+ TWL4030_VPLL2_DEV_GRP);
+ }
+ gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 1);
+ lcd_enabled = 0;
+}
+
+static struct omap_display_data omap3_bug_display_data = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "lcd",
+ .panel_name = "sharp-ls037v7dw01",
+ .u.dpi.data_lines = 18,
+ .panel_enable = omap3_bug_panel_enable_lcd,
+ .panel_disable = omap3_bug_panel_disable_lcd,
+};
+
+static int omap3_bug_panel_enable_tv(struct omap_display *display)
+{
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+ ENABLE_VDAC_DEDICATED, TWL4030_VDAC_DEDICATED);
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+ ENABLE_VDAC_DEV_GRP, TWL4030_VDAC_DEV_GRP);
+ return 0;
+}
+
+static void omap3_bug_panel_disable_tv(struct omap_display *display)
+{
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x00,
+ TWL4030_VDAC_DEDICATED);
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x00,
+ TWL4030_VDAC_DEV_GRP);
+}
+
+static struct omap_display_data omap3_bug_display_data_tv = {
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .name = "tv",
+#if defined(CONFIG_OMAP2_VENC_OUT_TYPE_SVIDEO)
+ .u.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+#elif defined(CONFIG_OMAP2_VENC_OUT_TYPE_COMPOSITE)
+ .u.venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE,
+#endif
+ .panel_enable = omap3_bug_panel_enable_tv,
+ .panel_disable = omap3_bug_panel_disable_tv,
+};
+
+static int omap3_bug_panel_enable_dvi(struct omap_display *display)
+{
+ unsigned char val;
+
+ if (lcd_enabled) {
+ return -EINVAL;
+ }
+
+ if (omap_rev() > OMAP3430_REV_ES1_0) {
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+ ENABLE_VPLL2_DEDICATED, TWL4030_PLL2_DEDICATED);
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+ ENABLE_VPLL2_DEV_GRP, TWL4030_VPLL2_DEV_GRP);
+ }
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
+ REG_GPIODATADIR1);
+ val |= 0x80;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
+ REG_GPIODATADIR1);
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
+ REG_GPIODATAOUT1);
+ val |= 0x80;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
+ REG_GPIODATAOUT1);
+ dvi_enabled = 1;
+
+ return 0;
+}
+
+static void omap3_bug_panel_disable_dvi(struct omap_display *display)
+{
+ unsigned char val;
+
+ if (omap_rev() > OMAP3430_REV_ES1_0) {
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x0,
+ TWL4030_PLL2_DEDICATED);
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x0,
+ TWL4030_VPLL2_DEV_GRP);
+ }
+
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
+ REG_GPIODATADIR1);
+ val &= ~0x80;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
+ REG_GPIODATADIR1);
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
+ REG_GPIODATAOUT1);
+ val &= ~0x80;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
+ REG_GPIODATAOUT1);
+ dvi_enabled = 0;
+}
+
+static struct omap_display_data omap3_bug_display_data_dvi = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "dvi",
+ .panel_name = "panel-generic",
+ .u.dpi.data_lines = 24,
+ .panel_enable = omap3_bug_panel_enable_dvi,
+ .panel_disable = omap3_bug_panel_disable_dvi,
+};
+
+static struct omap_dss_platform_data omap3_bug_dss_data = {
+ .num_displays = 3,
+ .displays = {
+ &omap3_bug_display_data,
+ &omap3_bug_display_data_dvi,
+ &omap3_bug_display_data_tv,
+ }
+};
+static struct platform_device omap3_bug_dss_device = {
+ .name = "omap-dss",
+ .id = -1,
+ .dev = {
+ .platform_data = &omap3_bug_dss_data,
+ },
+};
+#else /* CONFIG_OMAP2_DSS */
+static struct platform_device omap3_bug_lcd_device = {
+ .name = "omap3bug_lcd",
+ .id = -1,
+};
+static struct omap_lcd_config omap3_bug_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+#endif /* CONFIG_OMAP2_DSS */
+
+
+static struct resource bmi_slot1_resources[] = {
+ [0] = {
+ .start = 16,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = 21,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource bmi_slot2_resources[] = {
+ [0] = {
+ .start = 14,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = 15,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource bmi_slot3_resources[] = {
+ [0] = {
+ .start = 22,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = 23,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource bmi_slot4_resources[] = {
+ [0] = {
+ .start = 12,
+ .flags = IORESOURCE_IRQ,
+ },
+ [1] = {
+ .start = 13,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct omap_bmi_platform_data bmi_slot_pdata1 = {
+ .gpios = {218, 219, 220, 221},
+ .i2c_bus_no = 4,
+ .spi_cs = 1,
+};
+
+static struct omap_bmi_platform_data bmi_slot_pdata2 = {
+ .gpios = {-1,},
+ .i2c_bus_no = 5,
+ .spi_cs = -1,
+};
+
+static struct omap_bmi_platform_data bmi_slot_pdata3 = {
+ .gpios = {214, 215, 222, 223},
+ .i2c_bus_no = 6,
+ .spi_cs = 3,
+};
+
+static struct omap_bmi_platform_data bmi_slot_pdata4 = {
+ .gpios = {210, 211, 212, 213},
+ .i2c_bus_no = 7,
+ .spi_cs = 4,
+};
+
+static struct platform_device bmi_slot_devices[] = {
+ {
+ .name = "omap_bmi_slot",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bmi_slot1_resources),
+ .resource = bmi_slot1_resources,
+ .dev = {
+ .platform_data = &bmi_slot_pdata1,
+ },
+ },
+ {
+ .name = "omap_bmi_slot",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bmi_slot2_resources),
+ .resource = bmi_slot2_resources,
+ .dev = {
+ .platform_data = &bmi_slot_pdata2,
+ },
+ },
+ {
+ .name = "omap_bmi_slot",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(bmi_slot3_resources),
+ .resource = bmi_slot3_resources,
+ .dev = {
+ .platform_data = &bmi_slot_pdata3,
+ },
+ },
+ {
+ .name = "omap_bmi_slot",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(bmi_slot4_resources),
+ .resource = bmi_slot4_resources,
+ .dev = {
+ .platform_data = &bmi_slot_pdata4,
+ },
+ },
+};
+
+
+static void omap_init_bmi_slots(void)
+{
+ int i;
+
+ // gpio_direction_output(156, false);
+ // gpio_direction_output(159, false);
+
+ for (i = 0; i < ARRAY_SIZE(bmi_slot_devices); i++) {
+ if (platform_device_register(&bmi_slot_devices[i]) < 0)
+ dev_err(&bmi_slot_devices[i].dev,
+ "Unable to register BMI slot\n");
+ }
+}
+
+static struct resource omap3_bug_pwr_switch_resources[] = {
+ [0] = {
+ .start = TWL4030_PWR_IRQ_BASE,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device omap3_bug_pwr_switch = {
+ .name = "twl4030_pwrbutton",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(omap3_bug_pwr_switch_resources),
+ .resource = omap3_bug_pwr_switch_resources,
+};
+
+
+
+static void __init omap3_bug_init_irq(void)
+{
+ omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL);
+ omap_init_irq();
+ omap_gpio_init();
+}
+
+static struct omap_board_config_kernel omap3_bug_config[] __initdata = {
+#ifndef CONFIG_OMAP2_DSS
+ { OMAP_TAG_LCD, &omap3_bug_lcd_config },
+#endif
+};
+
+static struct platform_device *omap3_bug_devices[] __initdata = {
+#ifdef CONFIG_OMAP2_DSS
+ &omap3_bug_dss_device,
+ &omap3bug_vout_device,
+#else /* CONFIG_OMAP2_DSS */
+ &omap3_bug_lcd_device,
+#endif /* CONFIG_OMAP2_DSS */
+ &omap3_bug_pwr_switch,
+};
+
+
+static struct twl4030_hsmmc_info mmc[] __initdata = {
+ {
+ .mmc = 1,
+ .wires = 4,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = 63,
+ },
+ {
+ .mmc = 2,
+ .wires = 4,
+ .gpio_cd = 170,
+ //.gpio_wp = 63,
+ .ocr_mask = MMC_VDD_32_33,
+ },
+ {
+ .mmc = 3,
+ .wires = 1,
+ .gpio_cd = -EINVAL,
+ .gpio_wp = -EINVAL,
+ .ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33,
+ },
+ {} /* Terminator */
+};
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "omap3bug::ledb",
+ /* normally not visible (board underside) */
+ .default_trigger = "default-on",
+ .gpio = -EINVAL, /* gets replaced */
+ .active_low = true,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+
+static int omap3bug_twl_gpio_setup(struct device *dev,
+ unsigned gpio, unsigned ngpio)
+{
+ /* gpio + 0 is "mmc0_cd" (input/IRQ) */
+ mmc[0].gpio_cd = gpio + 0;
+ twl4030_mmc_init(mmc);
+ bug_vmmc1_supply.dev = mmc[0].dev;
+ /* Most GPIOs are for USB OTG. Some are mostly sent to
+ * the P2 connector; notably LEDA for the LCD backlight.
+ */
+
+ /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
+ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+
+ platform_device_register(&leds_gpio);
+
+ return 0;
+}
+
+static int omap3bug_ioexp_gpio_setup(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio, void *context)
+{
+ int r;
+ r = gpio_request(gpio + 14, "lt_en");
+ if (r) {
+ printk(KERN_ERR "ioexp_gpio: failed to get lt_en...\n");
+ return -1;
+ }
+ gpio_direction_output(gpio+14, 0);
+ gpio_free(gpio + 14);
+ return 0;
+}
+
+static int omap3bug_ioexp_gpio_teardown(struct i2c_client *client,
+ unsigned gpio, unsigned ngpio, void *context)
+{
+ int r;
+ r = gpio_direction_output(gpio+14, 1);
+ if (r) {
+ printk(KERN_ERR "ioexp_gpio: failed to reset lt_en...\n");
+ return -1;
+ }
+ gpio_free(gpio+14);
+ return 0;
+}
+
+static int omap3bug_spi_uart_gpio_setup(struct spi_device *spi, unsigned gpio, unsigned ngpio, void *context)
+{
+ int r;
+
+ printk(KERN_INFO "spi_uart_gpio: Setting up gpios...\n");
+ r = gpio_request(gpio + 4, "wifi_en");
+ if (r) {
+ printk(KERN_ERR "spi_uart_gpio: failed to get wifi_en...\n");
+ return r;
+ }
+ gpio_direction_output(gpio+4, 1);
+
+ mdelay(100);
+ r = gpio_request(157, "wifi_rst");
+ if (r) {
+ printk(KERN_ERR "spi_uart_gpio: failed to get wifi_rst...\n");
+ return r;
+ }
+ gpio_direction_output(157, 1);
+
+ r = gpio_request(156, "bt_rst");
+ if (r) {
+ printk(KERN_ERR "spi_uart_gpio: failed to get bt_rst...\n");
+ return r;
+ }
+ gpio_direction_output(156, 1);
+
+ r = gpio_request(163, "wifi_wakeup");
+ if (r) {
+ printk(KERN_ERR "spi_uart_gpio: failed to get wifi_wakeup...\n");
+ return r;
+ }
+ gpio_direction_output(163, 0);
+
+ mdelay(100);
+ gpio_set_value (163, 1);
+ gpio_set_value (157, 0);
+
+ mdelay(100);
+ gpio_set_value (157, 1);
+ gpio_set_value (156, 0);
+ mdelay(100);
+ gpio_set_value (156, 1);
+
+
+ printk(KERN_INFO "spi_uart_gpio: Freeing gpios...");
+ gpio_free(156);
+ gpio_free(157);
+ gpio_free(163);
+ return 0;
+}
+
+
+static void omap_init_twl4030(void)
+{
+ if (cpu_is_omap343x()) {
+ omap_cfg_reg(AF26_34XX_GPIO0);
+ omap_cfg_reg(L8_34XX_GPIO63);
+ }
+}
+
+#define TWL4030_VAUX2_1P8V 0x5
+#define ENABLE_VAUX2_DEV_GRP 0x20
+
+/* This is called from twl4030-core.c and is required by
+ * MUSB and EHCI on new OMAP3BUG.
+ */
+void usb_gpio_settings(void)
+{
+ unsigned char val;
+
+ /* enable VAUX2 for EHCI */
+ /*
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+ TWL4030_VAUX2_1P8V, TWL4030_VAUX2_DEDICATED);
+ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+ ENABLE_VAUX2_DEV_GRP, TWL4030_VAUX2_DEV_GRP);
+ */
+
+ /* Enable TWL GPIO Module */
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0x04, REG_GPIO_CTRL);
+
+ /*
+ * Configure GPIO-6 as output
+ */
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val, REG_GPIODATADIR1);
+ val |= 0x4;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val, REG_GPIODATADIR1);
+
+ /* Set GPIO6 = 1 */
+ twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val, REG_GPIODATAOUT1);
+ val |= 0x40;
+ twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val, REG_GPIODATAOUT1);
+
+
+}
+//EXPORT_SYMBOL(usb_gpio_settings);
+
+void gen_gpio_settings(void)
+{
+ int r;
+ r = gpio_request(107, "dock_rst");
+ if (r) {
+ printk(KERN_ERR "gen_gpio: failed to get dock_rst...\n");
+ return;
+ }
+ gpio_direction_output(107, 1);
+
+ r = gpio_request(42, "spi_uart_rst");
+ if (r) {
+ printk(KERN_ERR "gen_gpio: failed to get spi_uart_rst...\n");
+ return;
+ }
+ gpio_direction_output(42, 1);
+
+ return;
+
+}
+
+static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
+
+ .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
+ .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
+ .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
+
+ .chargepump = false,
+ .phy_reset = true,
+ .reset_gpio_port[0] = -EINVAL,
+ .reset_gpio_port[1] = 126,
+ .reset_gpio_port[2] = -EINVAL
+};
+
+
+static void __init omap3_bug_init(void)
+{
+
+ /* Get BUG board version and save it */
+// omap3bug_board_rev();
+
+ omap3_bug_i2c_init();
+
+ platform_add_devices(omap3_bug_devices, ARRAY_SIZE(omap3_bug_devices));
+ omap_board_config = omap3_bug_config;
+ omap_board_config_size = ARRAY_SIZE(omap3_bug_config);
+
+ spi_register_board_info(omap3bug_spi_board_info,
+ ARRAY_SIZE(omap3bug_spi_board_info));
+ omap_serial_init();
+// omap_init_twl4030();
+ usb_gpio_settings();
+ usb_musb_init();
+ usb_ehci_init(&ehci_pdata);
+ gen_gpio_settings();
+ omap3bug_flash_init();
+// ads7846_dev_init();
+#ifdef CONFIG_OMAP2_DSS
+// omap3_bug_display_init();
+#endif /* CONFIG_OMAP2_DSS */
+#if 0
+ if (get_omap3bug_board_rev() >= OMAP3BUG_BOARD_GEN_2) {
+ dec_i2c_id = 0x5C;
+ is_dec_onboard = 1;
+ } else {
+ dec_i2c_id = 0x5D;
+ is_dec_onboard = 0;
+ }
+ omap3bugdc_init(is_dec_onboard, 3, dec_i2c_id);
+#endif
+ omap_init_bmi_slots();
+}
+
+static void __init omap3_bug_map_io(void)
+{
+ omap2_set_globals_343x();
+ omap2_map_common_io();
+}
+
+MACHINE_START(OMAP3EVM, "OMAP3 BUG")
+ /* Maintainer: Matt Isaacs - BugLabs, inc */
+ .phys_io = 0x48000000,
+ .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
+ .boot_params = 0x80000100,
+ .map_io = omap3_bug_map_io,
+ .init_irq = omap3_bug_init_irq,
+ .init_machine = omap3_bug_init,
+ .timer = &omap_timer,
+MACHINE_END
View
81 arch/arm/mach-omap2/twl4030-generic-scripts.c
@@ -0,0 +1,81 @@
+/*
+ * arch/arm/mach-omap2/twl4030-generic-scripts.c
+ *
+ * Generic power control scripts for TWL4030
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Copyright (C) 2006 Texas Instruments, Inc
+ *
+ * Written by Kalle Jokiniemi
+ * Peter De Schrijver <peter.de-schrijver@nokia.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file "COPYING" in the main directory of this
+ * archive for more details.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef CONFIG_TWL4030_POWER
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/i2c/twl4030.h>
+
+/*
+ * This script instructs twl4030 to first put the Reset and Control (RC)
+ * resources to sleep and then all the other resources.
+ */
+
+static struct twl4030_ins sleep_on_seq[] __initdata = {
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0,
+ RES_STATE_SLEEP), 4},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_ALL, RES_TYPE2_R0,
+ RES_STATE_SLEEP), 4},
+};
+
+static struct twl4030_script sleep_on_script __initdata = {
+ .script = sleep_on_seq,
+ .size = ARRAY_SIZE(sleep_on_seq),
+ .flags = TRITON_SLEEP_SCRIPT,
+};
+
+/*
+ * This script instructs twl4030 to first enable CLKEN, then wakeup the
+ * regulators and then all other resources.
+ */
+
+static struct twl4030_ins wakeup_seq[] __initdata = {
+ {MSG_SINGULAR(DEV_GRP_NULL, 0x17, RES_STATE_ACTIVE), 0x30},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PP_PR, RES_TYPE_ALL, RES_TYPE2_R0,
+ RES_STATE_ACTIVE), 0x37},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_ALL, RES_TYPE_ALL, RES_TYPE2_R0,
+ RES_STATE_ACTIVE), 0x2},
+};
+
+static struct twl4030_script wakeup_script __initdata = {
+ .script = wakeup_seq,
+ .size = ARRAY_SIZE(wakeup_seq),
+ .flags = TRITON_WAKEUP12_SCRIPT | TRITON_WAKEUP3_SCRIPT,
+};
+
+static struct twl4030_script *twl4030_scripts[] __initdata = {
+ &sleep_on_script,
+ &wakeup_script,
+};
+
+struct twl4030_power_data generic3430_t2scripts_data __initdata = {
+ .scripts = twl4030_scripts,
+ .size = ARRAY_SIZE(twl4030_scripts),
+};
+
+
+#endif /* CONFIG_TWL4030_POWER */
View
13 arch/arm/mach-omap2/twl4030-generic-scripts.h
@@ -0,0 +1,13 @@
+#ifndef __TWL4030_GENERIC_SCRIPTS_H
+#define __TWL4030_GENERIC_SCRIPTS_H
+
+#include <linux/i2c/twl4030.h>
+
+#ifdef CONFIG_TWL4030_POWER
+extern struct twl4030_power_data generic3430_t2scripts_data;
+#define GENERIC3430_T2SCRIPTS_DATA &generic3430_t2scripts_data
+#else
+#define GENERIC3430_T2SCRIPTS_DATA NULL
+#endif /* CONFIG_TWL4030_POWER */
+
+#endif
View
17 drivers/bmi/Kconfig
@@ -0,0 +1,17 @@
+#
+# BMI Infrastructure
+#
+
+menuconfig BMI
+ tristate "BMI"
+ depends on I2C
+ default n
+ ---help---
+ BMI bus infrastructure
+
+if BMI
+
+source drivers/bmi/slots/Kconfig
+source drivers/bmi/pims/Kconfig
+
+endif # BMI
View
8 drivers/bmi/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the bmi bus drivers.
+#
+
+obj-$(CONFIG_BMI) += core/
+obj-$(CONFIG_BMI) += slots/
+obj-$(CONFIG_BMI) += pims/
+
View
7 drivers/bmi/core/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for BMI subsystem core
+#
+
+#bmicore-objs := core.o slot.o
+
+obj-$(CONFIG_BMI) += core.o driver.o slot.o eeprom.o
View
319 drivers/bmi/core/core.c
@@ -0,0 +1,319 @@
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kobject.h>
+#include <linux/bmi.h>
+
+
+static DEFINE_MUTEX(core_lock);
+
+static struct class *bmi_class;
+
+
+struct class* bmi_get_class (void)
+{
+ return bmi_class;
+};
+EXPORT_SYMBOL(bmi_get_class);
+
+
+/**
+ * bmi_device_get - increments the reference count of the bmi device structure
+ * @dev: the device being referenced
+ *
+ * Each live reference to a device should be refcounted.
+ *
+ * Drivers for BMI devices should normally record such references in
+ * their probe() methods, when they bind to a device, and release
+ * them by calling bmi_dev_put(), in their disconnect() methods.
+ *
+ * A pointer to the device with the incremented reference counter is returned.
+ */
+struct bmi_device *bmi_dev_get(struct bmi_device *dev)
+{
+ if (dev)
+ get_device(&dev->dev);
+ return dev;
+}
+
+
+/**
+ * bmi_device_put - release a use of the bmi device structure
+ * @dev: device that's been disconnected
+ *
+ * Must be called when a user of a device is finished with it. When the last
+ * user of the device calls this function, the memory of the device is freed.
+ */
+void bmi_dev_put(struct bmi_device *dev)
+{
+ if (dev)
+ put_device(&dev->dev);
+}
+
+
+/**
+ * bmi_match_one_id - Tell if a BMI device structure has a matching
+ * BMI device id structure
+ * @id: single BMI device id structure to match
+ * @bdev: the BMI device structure to match against
+ *
+ * Returns the matching bmi_device_id structure or %NULL if there is no match.
+ */
+
+static const struct bmi_device_id *bmi_match_one_id(const struct bmi_device_id *id,
+ const struct bmi_device *bdev)
+{
+ if ((id->vendor == bdev->vendor) &&
+ (id->product == bdev->product) &&
+ ((id->revision == bdev->revision) || (id->revision == BMI_ANY)))
+ return id;
+ return NULL;
+}
+
+
+/**
+ * bmi_match_id - See if a BMI device matches a given bmi_device_id table
+ * @ids: array of BMI device id structures to search in
+ * @bdev: the BMI device structure to match against.
+ *
+ * Used by a driver to check whether a BMI device present in the
+ * system is in its list of supported devices. Returns the matching
+ * bmi_device_id structure or %NULL if there is no match.
+ *
+ */
+
+
+const struct bmi_device_id *bmi_match_id(const struct bmi_device_id *ids,
+ struct bmi_device *bdev)
+{
+ if (ids) {
+ while (ids->vendor) {
+ if (bmi_match_one_id(ids, bdev))
+ return ids;
+ ids++;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * bmi_device_match - Tell if a BMI device structure has a matching BMI device id structure
+ * @dev: the BMI device structure to match against
+ * @drv: the device driver to search for matching PCI device id structures
+ *
+ * Used by a driver to check whether a BMI device present in the
+ * system is in its list of supported devices. Returns the matching
+ * bmi_device_id structure or %NULL if there is no match.
+ */
+
+
+static int bmi_device_match(struct device *dev, struct device_driver *driver)
+{
+ struct bmi_device *bmi_dev = to_bmi_device(dev);
+ struct bmi_driver *bmi_drv = to_bmi_driver(driver);
+ const struct bmi_device_id *found_id;
+
+ found_id = bmi_match_id(bmi_drv->id_table, bmi_dev);
+
+ if (found_id)
+ return 1;
+
+ printk(KERN_INFO "BMI: No matching Driver...\n");
+ return 0;
+}
+
+/*
+ * Uevent Generation for hotplug
+ */
+
+static int bmi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ struct bmi_device *bdev = to_bmi_device(dev);
+
+ if (!dev)
+ return -ENODEV;
+
+ if (add_uevent_var(env, "BMIBUS_SLOT=%01X", bdev->slot->slotnum)) {
+ return -ENOMEM;
+ }
+ if (add_uevent_var(env, "BMIBUS_VENDOR=%04X", bdev->vendor)) {
+ return -ENOMEM;
+ }
+ if (add_uevent_var(env, "BMIBUS_PRODUCT=%04X", bdev->product)) {
+ return -ENOMEM;
+ }
+ if (add_uevent_var(env, "BMIBUS_REV=%04X", bdev->revision)) {
+ return -ENOMEM;
+ }
+ if (add_uevent_var(env, "MODALIAS=bmi:v%04Xp%04Xr%04X",
+ bdev->vendor, bdev->product,
+ bdev->revision)) {
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+
+struct bmi_device *bmi_alloc_dev(struct bmi_slot *slot)
+{
+ struct bmi_device *dev;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev) {
+ printk(KERN_ERR "BMI: Couldn't Allocate bmi_device structure...\n");
+ return NULL;
+ }
+
+ device_initialize(&dev->dev);
+ dev->dev.bus = &bmi_bus_type;
+ dev_set_name(&dev->dev, "bmi-dev-%d",slot->slotnum);
+ dev->dev.parent = &slot->slotdev;
+ dev->slot = slot;
+
+ return dev;
+}
+
+
+
+/**
+ * __bmi_probe()
+ * @drv: driver to call to check if it wants the BMI device
+ * @bmi_dev: BMI device being probed
+ *
+ * returns 0 on success, else error.
+ * side-effect: bmi_dev->driver is set to drv when drv claims bmi_dev.
+ */
+static int
+__bmi_probe(struct bmi_driver *driver, struct bmi_device *bmi_dev)
+{
+ int error = 0;
+
+ if (!bmi_dev->driver && driver->probe) {
+
+ error = driver->probe(bmi_dev);
+ if (error >= 0) {
+ // bmi_device -> bmi_driver (bmi-bus level )
+ bmi_dev->driver = driver;
+ error = 0;
+ }
+ }
+ return error;
+}
+
+static int bmi_device_probe (struct device *dev)
+{
+ int error = 0;
+ struct bmi_driver *drv;
+ struct bmi_device *bmi_dev;
+
+ //By this time, we have already been match()ed against a driver.
+
+ // device -> device_driver. (driver-core level)
+
+ drv = to_bmi_driver(dev->driver);
+ bmi_dev = to_bmi_device(dev);
+
+
+ bmi_dev_get(bmi_dev);
+
+ error = __bmi_probe(drv, bmi_dev);
+ if (error)
+ bmi_dev_put(bmi_dev);
+ else
+ kobject_uevent(&dev->kobj, KOBJ_ADD);
+
+ return error;
+}
+
+
+
+static int bmi_device_remove (struct device *dev)
+{
+ struct bmi_device * bmi_dev;
+ struct bmi_driver * driver;
+
+ bmi_dev = to_bmi_device(dev);
+ driver = bmi_dev->driver;
+
+ if (driver) {
+ if (driver->remove)
+ driver->remove(bmi_dev);
+ bmi_dev->driver = NULL;
+ }
+
+ kobject_uevent(&dev->kobj, KOBJ_REMOVE);
+ bmi_dev_put(bmi_dev);
+ return 0;
+}
+
+static void bmi_device_shutdown(struct device * dev)
+{
+ return;
+}
+
+static int bmi_device_suspend (struct device * dev, pm_message_t state)
+{
+ return -1;
+}
+
+static int bmi_device_suspend_late (struct device * dev, pm_message_t state)
+{
+ return -1;
+}
+
+static int bmi_device_resume_early (struct device * dev)
+{
+ return -1;
+}
+
+static int bmi_device_resume (struct device * dev)
+{
+ return -1;
+}
+
+
+
+struct bus_type bmi_bus_type = {
+ .name = "bmi",
+ .match = bmi_device_match,
+ .uevent = bmi_device_uevent,
+ .probe = bmi_device_probe,
+ .remove = bmi_device_remove,
+ .shutdown = bmi_device_shutdown,
+ .suspend = bmi_device_suspend,
+ // .suspend_late = bmi_device_suspend_late,
+ // .resume_early = bmi_device_resume_early,
+ .resume = bmi_device_resume,
+};
+
+static int __init bmi_init(void)
+{
+ int ret = 0;
+
+ ret = bus_register(&bmi_bus_type);
+ if (ret) {
+ printk(KERN_ERR "BMI: (bmi_init) - Bus registration failed...\n");
+ return ret;
+ }
+
+ // ret = class_register(&bmi_class);
+ bmi_class = class_create(THIS_MODULE, "bmi");
+ if (ret) {
+ printk(KERN_ERR "BMI: (bmi_init) - Failed to register BMI Class...\n");
+ bmi_class = NULL;
+ bus_unregister(&bmi_bus_type);
+ }
+ return ret;
+}
+
+static void __exit bmi_cleanup(void)
+{
+ bmi_class = NULL;
+ bus_unregister(&bmi_bus_type);
+}
+
+//subsys_initcall(bmi_init);
+module_init(bmi_init);
+module_exit(bmi_cleanup);
View
35 drivers/bmi/core/device.c
@@ -0,0 +1,35 @@
+
+
+// bmi_device accessors
+static inline int bmi_device_get_status_irq (struct bmi_device *bdev)
+{
+ return (bdev->slot->status_irq);
+}
+
+static inline int bmi_device_get_present_irq (struct bmi_device *bdev)
+{
+ return (bdev->slot->present_irq);
+}
+
+static inline struct i2c_adapter* bmi_device_get_i2c_adapter (struct bmi_device *bdev)
+{
+ return (&bdev->slot->adap);
+}
+
+static inline int bmi_device_get_slot (struct bmi_device *bdev)
+{
+ return (bdev->slot->slotnum);
+}
+
+int bmi_device_present (struct bmi_device *bdev);
+struct bmi_device *bmi_device_get(struct bmi_device *dev);
+void bmi_device_put(struct bmi_device *dev);
+
+int bmi_device_read_inventory_eeprom ( struct bmi_device *bdev );
+int bmi_device_init ( struct bmi_device *bdev, struct bmi_info *info, struct bus_type *bmi_bus_type);
+void bmi_device_cleanup( struct bmi_device* bdev);
+int bmi_device_i2c_setup( struct bmi_device *bdev);
+void bmi_device_i2c_cleanup( struct bmi_device* bdev);
+int bmi_device_spi_setup( struct bmi_device *bdev, u32 speed, u8 mode, u8 bits_per_word);
+void bmi_device_spi_cleanup( struct bmi_device* bdev);
+struct spi_device *bmi_device_get_spi( struct bmi_device *bdev);
View
27 drivers/bmi/core/driver.c
@@ -0,0 +1,27 @@
+#include <linux/bmi.h>
+
+int __bmi_register_driver(struct bmi_driver *drv, struct module *owner)
+{
+ int error;
+
+ /* initialize common driver fields */
+ drv->driver.name = drv->name;
+ drv->driver.bus = &bmi_bus_type;
+ drv->driver.owner = owner;
+
+ /* register with core */
+ error = driver_register(&drv->driver);
+
+ return error;
+}
+
+
+void
+bmi_unregister_driver(struct bmi_driver *drv)
+{
+ driver_unregister(&drv->driver);
+}
+
+EXPORT_SYMBOL(__bmi_register_driver);
+EXPORT_SYMBOL(bmi_unregister_driver);
+
View
32 drivers/bmi/core/eeprom.c
@@ -0,0 +1,32 @@
+#include <linux/types.h>
+#include <linux/bmi/bmi-eeprom.h>
+
+
+static inline __u8 bmi_eeprom_checksum (struct bmi_eeprom_data *raw)
+{
+ int i;
+ __u8 sum = 0;
+ __u8 *buf = (__u8*)raw;
+
+ for (i = 0; i < (sizeof (struct bmi_eeprom_data) - 1); i++) {
+ sum ^= *buf++;
+ }
+ return sum;
+}
+
+
+int bmi_eeprom_checksum_validate (struct bmi_eeprom_data *raw)
+{
+ int ret = 0;
+ u8 calcsum;
+
+ calcsum = bmi_eeprom_checksum (raw);
+
+ if (calcsum != raw->checksum) {
+ //Rework: add conditional debug messages here
+ ret = -1;
+ }
+ return ret;
+}
+
+
View
472 drivers/bmi/core/slot.c
@@ -0,0 +1,472 @@
+/* Matt Isaacs - Kick ass platform independant BMI implementation */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/completion.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/freezer.h>
+#include <linux/idr.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/bmi.h>
+#include <linux/bmi/bmi-slot.h>
+
+static DEFINE_MUTEX(slot_lock);
+static DEFINE_IDR(bmi_slot_idr);
+
+
+//#include "slot.h"
+
+/*
+struct slot_driver {
+ const char *description;
+
+ irq_return_t (*irq) (struct bmi_slot);
+ int (*start) (struct bmi_slot);
+ int (*stop) (struct bmi_slot);
+}
+*/
+
+static struct task_struct *kslotd_task;
+
+static DEFINE_SPINLOCK(slot_event_lock);
+static LIST_HEAD(slot_event_list);
+static DECLARE_WAIT_QUEUE_HEAD(kslotd_wait);
+
+static struct i2c_board_info at24c02_info = {
+ I2C_BOARD_INFO("at24c02", 0XA0 >> 1),
+};
+
+static void bmi_slot_work_handler(struct work_struct * work);
+
+struct bmi_slot* bmi_get_slot(int slotnum)
+{
+ struct bmi_slot *slot;
+
+ mutex_lock(&slot_lock);
+ slot = (struct bmi_slot*)idr_find(&bmi_slot_idr, slotnum);
+ if (slot && !try_module_get(slot->owner))
+ slot = NULL;
+
+ mutex_unlock(&slot_lock);
+
+ return slot;
+}
+
+void bmi_slot_power_on (int num)
+{
+ struct bmi_slot *slot = bmi_get_slot(num);
+
+ if (!slot) {
+ printk(KERN_ERR "BMI: Slot %d doesn't exist...\n", num);
+ return;
+ }
+
+ if (slot->actions->power_on)
+ slot->actions->power_on(slot);
+ else
+ printk(KERN_INFO "BMI: Slot %d power is always on...\n", num);
+ return;
+}
+
+void bmi_slot_power_off (int num)
+{
+ struct bmi_slot *slot = bmi_get_slot(num);
+
+ if (!slot) {
+ printk(KERN_ERR "BMI: Slot %d doesn't exist...\n", num);
+ return;
+ }
+
+ if (slot->actions->power_off)
+ slot->actions->power_off(slot);
+ else
+ printk(KERN_INFO "BMI: Slot %d power is always on...\n", num);
+ return;
+}
+
+void bmi_slot_gpio_configure (int num, int gpio)
+{
+ struct bmi_slot *slot = bmi_get_slot(num);
+
+ if (!slot) {
+ printk(KERN_ERR "BMI: Slot %d doesn't exist...\n", num);
+ return;
+ }
+
+ if (slot->actions->gpio_config)
+ slot->actions->gpio_config(slot, gpio);
+ else
+ printk(KERN_INFO "BMI: Slot GPIO not configurable...\n");
+ return;
+
+}
+EXPORT_SYMBOL(bmi_slot_gpio_configure);
+
+int bmi_slot_gpio_get(int num)
+{
+ struct bmi_slot *slot = bmi_get_slot(num);
+
+ if (!slot) {
+ printk(KERN_ERR "BMI: Slot %d doesn't exist...\n", num);
+ return -ENODEV;
+ }
+
+ if (slot->actions->gpio_get)
+ return slot->actions->gpio_get(slot);
+
+ printk(KERN_INFO "BMI: Slot GPIO not writable...\n");
+ return -EIO;
+}
+EXPORT_SYMBOL(bmi_slot_gpio_get);
+
+void bmi_slot_gpio_set(int num, int data)
+{
+ struct bmi_slot *slot = bmi_get_slot(num);
+
+ if (!slot) {
+ printk(KERN_ERR "BMI: Slot %d doesn't exist...\n", num);
+ return;
+ }
+
+ if (slot->actions->gpio_set)
+ slot->actions->gpio_set(slot, data);
+ else
+ printk(KERN_INFO "BMI: Slot GPIO not writable...\n");
+ return;
+}
+EXPORT_SYMBOL(bmi_slot_gpio_set);
+
+void bmi_slot_gpio_write_bit(int num, int gpio, int data)
+{
+ return;
+}
+
+int bmi_slot_gpio_read_bit (int num, int gpio)
+{
+ int gpdat;
+ int bit;
+
+ gpdat = bmi_slot_gpio_get(num);
+ bit = (gpdat & (1 << gpio)) ? 1 : 0;
+ return bit;
+}
+
+
+// NOTE: When a plug-in module is removed, the gpios should be returned to inputs.
+// All requested slot resourece should be released.
+// The slot should be powered down.
+
+void bmi_slot_gpio_configure_all_as_inputs (int slot)
+{
+ return;
+}
+
+
+void bmi_slot_uart_enable (int num)
+{
+ struct bmi_slot *slot = bmi_get_slot(num);
+
+ if (!slot) {
+ printk(KERN_ERR "BMI: Slot %d doesn't exist...\n", num);
+ return;
+ }
+
+ if (slot->actions->uart_enable)
+ return slot->actions->uart_enable(slot);
+
+ printk(KERN_INFO "BMI: UART always enabled...\n");
+ return;
+}
+EXPORT_SYMBOL(bmi_slot_uart_enable);
+
+void bmi_slot_uart_disable (int num)
+{
+
+ return;
+}
+EXPORT_SYMBOL(bmi_slot_uart_disable);
+
+void bmi_slot_spi_enable (int num)
+{
+
+ return;
+}
+EXPORT_SYMBOL(bmi_slot_spi_enable);
+
+void bmi_slot_spi_disable (int num)
+{
+ return;
+}
+EXPORT_SYMBOL(bmi_slot_spi_disable);
+
+void bmi_slot_audio_enable (int num)
+{
+
+ return;
+}
+EXPORT_SYMBOL(bmi_slot_audio_enable);
+
+void bmi_slot_audio_disable (int num)
+{
+
+ return;
+}
+EXPORT_SYMBOL(bmi_slot_audio_disable);
+
+void bmi_slot_battery_enable (int num)
+{
+
+ return;
+}
+EXPORT_SYMBOL(bmi_slot_battery_enable);
+
+void bmi_slot_battery_disable (int num)
+{
+
+ return;
+}
+EXPORT_SYMBOL(bmi_slot_battery_disable);
+
+int bmi_slot_module_present (int num)
+{
+ struct bmi_slot *slot = bmi_get_slot(num);
+ // slot->actions->gpio_set
+ if (slot->actions->present != NULL)
+ return slot->actions->present(slot);
+ else
+ printk(KERN_INFO "BMI: Slot Driver incomplete. No presence detection...\n");
+ return 0;
+}
+
+int bmi_slot_read_eeprom(struct bmi_slot *slot, u8* data)
+{
+ unsigned char i = 0;
+ int ret;
+
+ if (slot->eeprom == NULL) {
+ printk(KERN_INFO "Can't get eeprom client...\n");
+ ret = -EIO;
+ }
+ else {
+ ret = i2c_master_send(slot->eeprom, &i, 1);
+ if (ret == 1)
+ ret = i2c_master_recv(slot->eeprom, data, sizeof(struct bmi_eeprom_data));
+ }
+ return ret;
+}
+
+int bmi_slot_status_irq_state (int slot)
+{
+ int state = 0;
+ return state;
+}
+
+
+#define DEBOUNCE_DELAY msecs_to_jiffies(1000)
+
+static irqreturn_t bmi_slot_irq_handler(int irq, void *dev_id)
+{
+ struct bmi_slot *slot = dev_id;
+
+ disable_irq_nosync(irq);
+ printk(KERN_INFO " BMI: IRQ Triggered on slot: %d\n", slot->slotnum);
+ schedule_delayed_work(&slot->work, DEBOUNCE_DELAY);
+ return IRQ_HANDLED;
+}
+
+static void bmi_slot_work_handler(struct work_struct * work)
+{
+ struct bmi_slot *slot;
+ struct bmi_device *bdev;