+struct {
+ struct clk *mclk;
+ int initialized;
+} h3_tsc2101;
+
+#define TSC2101_MUX_MCLK_ON V5_1710_MCLK_ON
+#define TSC2101_MUX_MCLK_OFF V5_1710_MCLK_OFF
+
+static int h3_tsc2101_init(struct spi_device *spi)
+{
+ u8 io_exp_val;
+ int r;
+
+ if (h3_tsc2101.initialized) {
+ printk(KERN_ERR "tsc2101: already initialized\n");
+ return -ENODEV;
+ }
+
+ /* Get the MCLK */
+ h3_tsc2101.mclk = clk_get(&spi->dev, "mclk");
+ if (IS_ERR(h3_tsc2101.mclk)) {
+ dev_err(&spi->dev, "unable to get the clock MCLK\n");
+ return PTR_ERR(h3_tsc2101.mclk);
+ }
+ if ((r = clk_set_rate(h3_tsc2101.mclk, 12000000)) < 0) {
+ dev_err(&spi->dev, "unable to set rate to the MCLK\n");
+ goto err;
+ }
+
+ if ((r = read_gpio_expa(&io_exp_val, 0x24))) {
+ dev_err(&spi->dev, "error reading from I/O EXPANDER\n");
+ goto err;
+ }
+ io_exp_val |= 0x8;
+ if ((r = write_gpio_expa(io_exp_val, 0x24))) {
+ dev_err(&spi->dev, "error writing to I/O EXPANDER\n");
+ goto err;
+ }
+
+ omap_cfg_reg(N14_1610_UWIRE_CS0);
+ omap_cfg_reg(TSC2101_MUX_MCLK_OFF);
+
+ return 0;
+err:
+ clk_put(h3_tsc2101.mclk);
+ return r;
+}
+
+static void h3_tsc2101_cleanup(struct spi_device *spi)
+{
+ clk_put(h3_tsc2101.mclk);
+ omap_cfg_reg(TSC2101_MUX_MCLK_OFF);
+}
+
+static void h3_tsc2101_enable_mclk(struct spi_device *spi)
+{
+ omap_cfg_reg(TSC2101_MUX_MCLK_ON);
+ clk_enable(h3_tsc2101.mclk);
+}
+
+static void h3_tsc2101_disable_mclk(struct spi_device *spi)
+{
+ clk_disable(h3_tsc2101.mclk);
+ omap_cfg_reg(R10_1610_MCLK_OFF);
+}
+
+static struct tsc2101_platform_data h3_tsc2101_platform_data = {
+ .init = h3_tsc2101_init,
+ .cleanup = h3_tsc2101_cleanup,
+ .enable_mclk = h3_tsc2101_enable_mclk,
+ .disable_mclk = h3_tsc2101_disable_mclk,
+};
+
+static struct spi_board_info h3_spi_board_info[] __initdata = {
+ [0] = {
+ .modalias = "tsc2101",
+ .bus_num = 2,
+ .chip_select = 0,
+ .max_speed_hz = 16000000,
+ .platform_data = &h3_tsc2101_platform_data,
+ },
+};
+