static void brightness_set(struct led_classdev *cdev, enum led_brightness value) { struct platform_device *pdev = to_platform_device(cdev->dev->parent); const struct mfd_cell *cell = mfd_get_cell(pdev); struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); u32 timebase; unsigned int base; timebase = (value == LED_OFF) ? 0 : (LED_EN|0x4); base = led_n_base[cell->id]; asic3_write_register(asic, (base + ASIC3_LED_PeriodTime), 32); asic3_write_register(asic, (base + ASIC3_LED_DutyTime), 32); asic3_write_register(asic, (base + ASIC3_LED_AutoStopCount), 0); asic3_write_register(asic, (base + ASIC3_LED_TimeBase), timebase); }
static int asic3_spi_process_byte(unsigned char data) { #define ASIC3_SPI_CTRL (_IPAQ_ASIC3_SPI_Base + _IPAQ_ASIC3_SPI_Control) #define ASIC3_SPI_TXDATA (_IPAQ_ASIC3_SPI_Base + _IPAQ_ASIC3_SPI_TxData) #define ASIC3_SPI_RXDATA (_IPAQ_ASIC3_SPI_Base + _IPAQ_ASIC3_SPI_RxData) #define SPI_CTRL_SEL (1 << 6) #define SPI_CTRL_SPIE (1 << 5) #define SPI_CTRL_SPE (1 << 4) unsigned long flags; unsigned int timeout; unsigned int ctrl; int result = 0; local_irq_save(flags); /* Enable interrupts */ ctrl = asic3_read_register(a3, ASIC3_SPI_CTRL) | SPI_CTRL_SPIE; asic3_write_register(a3, ASIC3_SPI_CTRL, ctrl); /* Set data to send */ asic3_write_register(a3, ASIC3_SPI_TXDATA, data); /* Start the transfer (duplex) */ asic3_write_register(a3, ASIC3_SPI_CTRL, (ctrl | SPI_CTRL_SPE)); /* Wait for transfer completion and receive data being ready */ for (timeout = 255; timeout > 0; timeout--) { if (!(asic3_read_register(a3, ASIC3_SPI_CTRL) & SPI_CTRL_SPE)){ udelay(20); /* wait for a while, or we'll miss it */ result = asic3_read_register(a3, ASIC3_SPI_RXDATA); break; } } /* Disable interrupts */ ctrl = asic3_read_register(a3, ASIC3_SPI_CTRL) & ~SPI_CTRL_SPIE; asic3_write_register(a3, ASIC3_SPI_CTRL, ctrl); local_irq_restore(flags); return result & 0xff; }
static int blink_set(struct led_classdev *cdev, unsigned long *delay_on, unsigned long *delay_off) { struct platform_device *pdev = to_platform_device(cdev->dev->parent); const struct mfd_cell *cell = mfd_get_cell(pdev); struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); u32 on; u32 off; unsigned int base; if (*delay_on > MAX_MS || *delay_off > MAX_MS) return -EINVAL; if (*delay_on == 0 && *delay_off == 0) { /* If both are zero then a sensible default should be chosen */ on = MS_TO_CLK(500); off = MS_TO_CLK(500); } else { on = MS_TO_CLK(*delay_on); off = MS_TO_CLK(*delay_off); if ((on + off) > MAX_CLK) return -EINVAL; } base = led_n_base[cell->id]; asic3_write_register(asic, (base + ASIC3_LED_PeriodTime), (on + off)); asic3_write_register(asic, (base + ASIC3_LED_DutyTime), on); asic3_write_register(asic, (base + ASIC3_LED_AutoStopCount), 0); asic3_write_register(asic, (base + ASIC3_LED_TimeBase), (LED_EN|0x4)); *delay_on = CLK_TO_MS(on); *delay_off = CLK_TO_MS(off); return 0; }
static void setup_h4300kbd(void) { asic3_set_clock_cdex(a3, CLOCK_CDEX_SPI, CLOCK_CDEX_SPI); asic3_set_clock_cdex(a3, CLOCK_CDEX_EX1, CLOCK_CDEX_EX1); udelay(20); asic3_set_gpio_dir_b(a3, GPIOB_KEYBOARD_IRQ, 0); asic3_set_gpio_out_b(a3, (GPIOB_MICRO_3V3_EN | GPIOB_KEYBOARD_WAKE_UP), (GPIOB_MICRO_3V3_EN | GPIOB_KEYBOARD_WAKE_UP) ); asic3_set_gpio_dir_c(a3, GPIOC_KEY_RXD, 0); asic3_set_gpio_alt_fn_c(a3, GPIOC_KEY_RXD | GPIOC_KEY_TXD | GPIOC_KEY_CLK, GPIOC_KEY_RXD | GPIOC_KEY_TXD | GPIOC_KEY_CLK); asic3_set_gpio_dir_d(a3, // disable h4100 buttons (GPIOD_TASK_BUTTON_N | GPIOD_MAIL_BUTTON_N | GPIOD_CONTACTS_BUTTON_N | GPIOD_CALENDAR_BUTTON_N), (GPIOD_TASK_BUTTON_N | GPIOD_MAIL_BUTTON_N | GPIOD_CONTACTS_BUTTON_N | GPIOD_CALENDAR_BUTTON_N)); asic3_write_register(a3, 0x400, 0xa104); }