aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/board-omap3stalker.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/board-omap3stalker.c')
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c220
1 files changed, 60 insertions, 160 deletions
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index bcd01d278c65..0c108a212ea2 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -26,6 +26,7 @@
26 26
27#include <linux/regulator/machine.h> 27#include <linux/regulator/machine.h>
28#include <linux/i2c/twl.h> 28#include <linux/i2c/twl.h>
29#include <linux/mmc/host.h>
29 30
30#include <mach/hardware.h> 31#include <mach/hardware.h>
31#include <asm/mach-types.h> 32#include <asm/mach-types.h>
@@ -38,13 +39,12 @@
38#include <plat/gpmc.h> 39#include <plat/gpmc.h>
39#include <plat/nand.h> 40#include <plat/nand.h>
40#include <plat/usb.h> 41#include <plat/usb.h>
41#include <plat/timer-gp.h> 42#include <video/omapdss.h>
42#include <plat/display.h> 43#include <video/omap-panel-generic-dpi.h>
43 44
44#include <plat/mcspi.h> 45#include <plat/mcspi.h>
45#include <linux/input/matrix_keypad.h> 46#include <linux/input/matrix_keypad.h>
46#include <linux/spi/spi.h> 47#include <linux/spi/spi.h>
47#include <linux/spi/ads7846.h>
48#include <linux/interrupt.h> 48#include <linux/interrupt.h>
49#include <linux/smsc911x.h> 49#include <linux/smsc911x.h>
50#include <linux/i2c/at24.h> 50#include <linux/i2c/at24.h>
@@ -52,52 +52,29 @@
52#include "sdram-micron-mt46h32m32lf-6.h" 52#include "sdram-micron-mt46h32m32lf-6.h"
53#include "mux.h" 53#include "mux.h"
54#include "hsmmc.h" 54#include "hsmmc.h"
55#include "timer-gp.h"
56#include "common-board-devices.h"
55 57
56#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) 58#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
59#include <plat/gpmc-smsc911x.h>
60
57#define OMAP3STALKER_ETHR_START 0x2c000000 61#define OMAP3STALKER_ETHR_START 0x2c000000
58#define OMAP3STALKER_ETHR_SIZE 1024 62#define OMAP3STALKER_ETHR_SIZE 1024
59#define OMAP3STALKER_ETHR_GPIO_IRQ 19 63#define OMAP3STALKER_ETHR_GPIO_IRQ 19
60#define OMAP3STALKER_SMC911X_CS 5 64#define OMAP3STALKER_SMC911X_CS 5
61 65
62static struct resource omap3stalker_smsc911x_resources[] = { 66static struct omap_smsc911x_platform_data smsc911x_cfg = {
63 [0] = { 67 .cs = OMAP3STALKER_SMC911X_CS,
64 .start = OMAP3STALKER_ETHR_START, 68 .gpio_irq = OMAP3STALKER_ETHR_GPIO_IRQ,
65 .end = 69 .gpio_reset = -EINVAL,
66 (OMAP3STALKER_ETHR_START + OMAP3STALKER_ETHR_SIZE - 1),
67 .flags = IORESOURCE_MEM,
68 },
69 [1] = {
70 .start = OMAP_GPIO_IRQ(OMAP3STALKER_ETHR_GPIO_IRQ),
71 .end = OMAP_GPIO_IRQ(OMAP3STALKER_ETHR_GPIO_IRQ),
72 .flags = (IORESOURCE_IRQ | IRQF_TRIGGER_LOW),
73 },
74};
75
76static struct smsc911x_platform_config smsc911x_config = {
77 .phy_interface = PHY_INTERFACE_MODE_MII,
78 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
79 .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
80 .flags = (SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS), 70 .flags = (SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS),
81}; 71};
82 72
83static struct platform_device omap3stalker_smsc911x_device = {
84 .name = "smsc911x",
85 .id = -1,
86 .num_resources = ARRAY_SIZE(omap3stalker_smsc911x_resources),
87 .resource = &omap3stalker_smsc911x_resources[0],
88 .dev = {
89 .platform_data = &smsc911x_config,
90 },
91};
92
93static inline void __init omap3stalker_init_eth(void) 73static inline void __init omap3stalker_init_eth(void)
94{ 74{
95 int eth_cs;
96 struct clk *l3ck; 75 struct clk *l3ck;
97 unsigned int rate; 76 unsigned int rate;
98 77
99 eth_cs = OMAP3STALKER_SMC911X_CS;
100
101 l3ck = clk_get(NULL, "l3_ck"); 78 l3ck = clk_get(NULL, "l3_ck");
102 if (IS_ERR(l3ck)) 79 if (IS_ERR(l3ck))
103 rate = 100000000; 80 rate = 100000000;
@@ -105,16 +82,7 @@ static inline void __init omap3stalker_init_eth(void)
105 rate = clk_get_rate(l3ck); 82 rate = clk_get_rate(l3ck);
106 83
107 omap_mux_init_gpio(19, OMAP_PIN_INPUT_PULLUP); 84 omap_mux_init_gpio(19, OMAP_PIN_INPUT_PULLUP);
108 if (gpio_request(OMAP3STALKER_ETHR_GPIO_IRQ, "SMC911x irq") < 0) { 85 gpmc_smsc911x_init(&smsc911x_cfg);
109 printk(KERN_ERR
110 "Failed to request GPIO%d for smc911x IRQ\n",
111 OMAP3STALKER_ETHR_GPIO_IRQ);
112 return;
113 }
114
115 gpio_direction_input(OMAP3STALKER_ETHR_GPIO_IRQ);
116
117 platform_device_register(&omap3stalker_smsc911x_device);
118} 86}
119 87
120#else 88#else
@@ -159,13 +127,18 @@ static void omap3_stalker_disable_lcd(struct omap_dss_device *dssdev)
159 lcd_enabled = 0; 127 lcd_enabled = 0;
160} 128}
161 129
130static struct panel_generic_dpi_data lcd_panel = {
131 .name = "generic",
132 .platform_enable = omap3_stalker_enable_lcd,
133 .platform_disable = omap3_stalker_disable_lcd,
134};
135
162static struct omap_dss_device omap3_stalker_lcd_device = { 136static struct omap_dss_device omap3_stalker_lcd_device = {
163 .name = "lcd", 137 .name = "lcd",
164 .driver_name = "generic_panel", 138 .driver_name = "generic_dpi_panel",
139 .data = &lcd_panel,
165 .phy.dpi.data_lines = 24, 140 .phy.dpi.data_lines = 24,
166 .type = OMAP_DISPLAY_TYPE_DPI, 141 .type = OMAP_DISPLAY_TYPE_DPI,
167 .platform_enable = omap3_stalker_enable_lcd,
168 .platform_disable = omap3_stalker_disable_lcd,
169}; 142};
170 143
171static int omap3_stalker_enable_tv(struct omap_dss_device *dssdev) 144static int omap3_stalker_enable_tv(struct omap_dss_device *dssdev)
@@ -207,13 +180,18 @@ static void omap3_stalker_disable_dvi(struct omap_dss_device *dssdev)
207 dvi_enabled = 0; 180 dvi_enabled = 0;
208} 181}
209 182
183static struct panel_generic_dpi_data dvi_panel = {
184 .name = "generic",
185 .platform_enable = omap3_stalker_enable_dvi,
186 .platform_disable = omap3_stalker_disable_dvi,
187};
188
210static struct omap_dss_device omap3_stalker_dvi_device = { 189static struct omap_dss_device omap3_stalker_dvi_device = {
211 .name = "dvi", 190 .name = "dvi",
212 .driver_name = "generic_panel",
213 .type = OMAP_DISPLAY_TYPE_DPI, 191 .type = OMAP_DISPLAY_TYPE_DPI,
192 .driver_name = "generic_dpi_panel",
193 .data = &dvi_panel,
214 .phy.dpi.data_lines = 24, 194 .phy.dpi.data_lines = 24,
215 .platform_enable = omap3_stalker_enable_dvi,
216 .platform_disable = omap3_stalker_disable_dvi,
217}; 195};
218 196
219static struct omap_dss_device *omap3_stalker_dss_devices[] = { 197static struct omap_dss_device *omap3_stalker_dss_devices[] = {
@@ -228,14 +206,6 @@ static struct omap_dss_board_info omap3_stalker_dss_data = {
228 .default_device = &omap3_stalker_dvi_device, 206 .default_device = &omap3_stalker_dvi_device,
229}; 207};
230 208
231static struct platform_device omap3_stalker_dss_device = {
232 .name = "omapdss",
233 .id = -1,
234 .dev = {
235 .platform_data = &omap3_stalker_dss_data,
236 },
237};
238
239static struct regulator_consumer_supply omap3stalker_vmmc1_supply = { 209static struct regulator_consumer_supply omap3stalker_vmmc1_supply = {
240 .supply = "vmmc", 210 .supply = "vmmc",
241}; 211};
@@ -275,7 +245,7 @@ static struct regulator_init_data omap3stalker_vsim = {
275static struct omap2_hsmmc_info mmc[] = { 245static struct omap2_hsmmc_info mmc[] = {
276 { 246 {
277 .mmc = 1, 247 .mmc = 1,
278 .wires = 4, 248 .caps = MMC_CAP_4_BIT_DATA,
279 .gpio_cd = -EINVAL, 249 .gpio_cd = -EINVAL,
280 .gpio_wp = 23, 250 .gpio_wp = 23,
281 }, 251 },
@@ -361,12 +331,11 @@ omap3stalker_twl_gpio_setup(struct device *dev,
361 */ 331 */
362 332
363 /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */ 333 /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */
364 gpio_request(gpio + TWL4030_GPIO_MAX, "EN_LCD_BKL"); 334 gpio_request_one(gpio + TWL4030_GPIO_MAX, GPIOF_OUT_INIT_LOW,
365 gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0); 335 "EN_LCD_BKL");
366 336
367 /* gpio + 7 == DVI Enable */ 337 /* gpio + 7 == DVI Enable */
368 gpio_request(gpio + 7, "EN_DVI"); 338 gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI");
369 gpio_direction_output(gpio + 7, 0);
370 339
371 /* TWL4030_GPIO_MAX + 1 == ledB (out, mmc0) */ 340 /* TWL4030_GPIO_MAX + 1 == ledB (out, mmc0) */
372 gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; 341 gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
@@ -389,7 +358,7 @@ static struct twl4030_usb_data omap3stalker_usb_data = {
389 .usb_mode = T2_USB_MODE_ULPI, 358 .usb_mode = T2_USB_MODE_ULPI,
390}; 359};
391 360
392static int board_keymap[] = { 361static uint32_t board_keymap[] = {
393 KEY(0, 0, KEY_LEFT), 362 KEY(0, 0, KEY_LEFT),
394 KEY(0, 1, KEY_DOWN), 363 KEY(0, 1, KEY_DOWN),
395 KEY(0, 2, KEY_ENTER), 364 KEY(0, 2, KEY_ENTER),
@@ -427,19 +396,15 @@ static struct twl4030_madc_platform_data omap3stalker_madc_data = {
427 .irq_line = 1, 396 .irq_line = 1,
428}; 397};
429 398
430static struct twl4030_codec_audio_data omap3stalker_audio_data = { 399static struct twl4030_codec_audio_data omap3stalker_audio_data;
431 .audio_mclk = 26000000,
432};
433 400
434static struct twl4030_codec_data omap3stalker_codec_data = { 401static struct twl4030_codec_data omap3stalker_codec_data = {
435 .audio_mclk = 26000000, 402 .audio_mclk = 26000000,
436 .audio = &omap3stalker_audio_data, 403 .audio = &omap3stalker_audio_data,
437}; 404};
438 405
439static struct regulator_consumer_supply omap3_stalker_vdda_dac_supply = { 406static struct regulator_consumer_supply omap3_stalker_vdda_dac_supply =
440 .supply = "vdda_dac", 407 REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
441 .dev = &omap3_stalker_dss_device.dev,
442};
443 408
444/* VDAC for DSS driving S-Video */ 409/* VDAC for DSS driving S-Video */
445static struct regulator_init_data omap3_stalker_vdac = { 410static struct regulator_init_data omap3_stalker_vdac = {
@@ -457,9 +422,9 @@ static struct regulator_init_data omap3_stalker_vdac = {
457}; 422};
458 423
459/* VPLL2 for digital video outputs */ 424/* VPLL2 for digital video outputs */
460static struct regulator_consumer_supply omap3_stalker_vpll2_supply = { 425static struct regulator_consumer_supply omap3_stalker_vpll2_supplies[] = {
461 .supply = "vdds_dsi", 426 REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
462 .dev = &omap3_stalker_lcd_device.dev, 427 REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
463}; 428};
464 429
465static struct regulator_init_data omap3_stalker_vpll2 = { 430static struct regulator_init_data omap3_stalker_vpll2 = {
@@ -473,8 +438,8 @@ static struct regulator_init_data omap3_stalker_vpll2 = {
473 .valid_ops_mask = REGULATOR_CHANGE_MODE 438 .valid_ops_mask = REGULATOR_CHANGE_MODE
474 | REGULATOR_CHANGE_STATUS, 439 | REGULATOR_CHANGE_STATUS,
475 }, 440 },
476 .num_consumer_supplies = 1, 441 .num_consumer_supplies = ARRAY_SIZE(omap3_stalker_vpll2_supplies),
477 .consumer_supplies = &omap3_stalker_vpll2_supply, 442 .consumer_supplies = omap3_stalker_vpll2_supplies,
478}; 443};
479 444
480static struct twl4030_platform_data omap3stalker_twldata = { 445static struct twl4030_platform_data omap3stalker_twldata = {
@@ -489,15 +454,8 @@ static struct twl4030_platform_data omap3stalker_twldata = {
489 .codec = &omap3stalker_codec_data, 454 .codec = &omap3stalker_codec_data,
490 .vdac = &omap3_stalker_vdac, 455 .vdac = &omap3_stalker_vdac,
491 .vpll2 = &omap3_stalker_vpll2, 456 .vpll2 = &omap3_stalker_vpll2,
492}; 457 .vmmc1 = &omap3stalker_vmmc1,
493 458 .vsim = &omap3stalker_vsim,
494static struct i2c_board_info __initdata omap3stalker_i2c_boardinfo[] = {
495 {
496 I2C_BOARD_INFO("twl4030", 0x48),
497 .flags = I2C_CLIENT_WAKE,
498 .irq = INT_34XX_SYS_NIRQ,
499 .platform_data = &omap3stalker_twldata,
500 },
501}; 459};
502 460
503static struct at24_platform_data fram_info = { 461static struct at24_platform_data fram_info = {
@@ -516,15 +474,7 @@ static struct i2c_board_info __initdata omap3stalker_i2c_boardinfo3[] = {
516 474
517static int __init omap3_stalker_i2c_init(void) 475static int __init omap3_stalker_i2c_init(void)
518{ 476{
519 /* 477 omap3_pmic_init("twl4030", &omap3stalker_twldata);
520 * REVISIT: These entries can be set in omap3evm_twl_data
521 * after a merge with MFD tree
522 */
523 omap3stalker_twldata.vmmc1 = &omap3stalker_vmmc1;
524 omap3stalker_twldata.vsim = &omap3stalker_vsim;
525
526 omap_register_i2c_bus(1, 2600, omap3stalker_i2c_boardinfo,
527 ARRAY_SIZE(omap3stalker_i2c_boardinfo));
528 omap_register_i2c_bus(2, 400, NULL, 0); 478 omap_register_i2c_bus(2, 400, NULL, 0);
529 omap_register_i2c_bus(3, 400, omap3stalker_i2c_boardinfo3, 479 omap_register_i2c_bus(3, 400, omap3stalker_i2c_boardinfo3,
530 ARRAY_SIZE(omap3stalker_i2c_boardinfo3)); 480 ARRAY_SIZE(omap3stalker_i2c_boardinfo3));
@@ -532,74 +482,32 @@ static int __init omap3_stalker_i2c_init(void)
532} 482}
533 483
534#define OMAP3_STALKER_TS_GPIO 175 484#define OMAP3_STALKER_TS_GPIO 175
535static void ads7846_dev_init(void)
536{
537 if (gpio_request(OMAP3_STALKER_TS_GPIO, "ADS7846 pendown") < 0)
538 printk(KERN_ERR "can't get ads7846 pen down GPIO\n");
539 485
540 gpio_direction_input(OMAP3_STALKER_TS_GPIO); 486static struct omap_board_config_kernel omap3_stalker_config[] __initdata = {
541 gpio_set_debounce(OMAP3_STALKER_TS_GPIO, 310); 487};
542}
543 488
544static int ads7846_get_pendown_state(void) 489static void __init omap3_stalker_init_early(void)
545{ 490{
546 return !gpio_get_value(OMAP3_STALKER_TS_GPIO); 491 omap2_init_common_infrastructure();
492 omap2_init_common_devices(mt46h32m32lf6_sdrc_params, NULL);
547} 493}
548 494
549static struct ads7846_platform_data ads7846_config = {
550 .x_max = 0x0fff,
551 .y_max = 0x0fff,
552 .x_plate_ohms = 180,
553 .pressure_max = 255,
554 .debounce_max = 10,
555 .debounce_tol = 3,
556 .debounce_rep = 1,
557 .get_pendown_state = ads7846_get_pendown_state,
558 .keep_vref_on = 1,
559 .settle_delay_usecs = 150,
560};
561
562static struct omap2_mcspi_device_config ads7846_mcspi_config = {
563 .turbo_mode = 0,
564 .single_channel = 1, /* 0: slave, 1: master */
565};
566
567struct spi_board_info omap3stalker_spi_board_info[] = {
568 [0] = {
569 .modalias = "ads7846",
570 .bus_num = 1,
571 .chip_select = 0,
572 .max_speed_hz = 1500000,
573 .controller_data = &ads7846_mcspi_config,
574 .irq = OMAP_GPIO_IRQ(OMAP3_STALKER_TS_GPIO),
575 .platform_data = &ads7846_config,
576 },
577};
578
579static struct omap_board_config_kernel omap3_stalker_config[] __initdata = {
580};
581
582static void __init omap3_stalker_init_irq(void) 495static void __init omap3_stalker_init_irq(void)
583{ 496{
584 omap_board_config = omap3_stalker_config;
585 omap_board_config_size = ARRAY_SIZE(omap3_stalker_config);
586 omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL);
587 omap_init_irq(); 497 omap_init_irq();
588#ifdef CONFIG_OMAP_32K_TIMER 498#ifdef CONFIG_OMAP_32K_TIMER
589 omap2_gp_clockevent_set_gptimer(12); 499 omap2_gp_clockevent_set_gptimer(12);
590#endif 500#endif
591 omap_gpio_init();
592} 501}
593 502
594static struct platform_device *omap3_stalker_devices[] __initdata = { 503static struct platform_device *omap3_stalker_devices[] __initdata = {
595 &omap3_stalker_dss_device,
596 &keys_gpio, 504 &keys_gpio,
597}; 505};
598 506
599static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { 507static struct usbhs_omap_board_data usbhs_bdata __initconst = {
600 .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, 508 .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
601 .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, 509 .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
602 .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, 510 .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
603 511
604 .phy_reset = true, 512 .phy_reset = true,
605 .reset_gpio_port[0] = -EINVAL, 513 .reset_gpio_port[0] = -EINVAL,
@@ -615,32 +523,25 @@ static struct omap_board_mux board_mux[] __initdata = {
615 OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE), 523 OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),
616 {.reg_offset = OMAP_MUX_TERMINATOR}, 524 {.reg_offset = OMAP_MUX_TERMINATOR},
617}; 525};
618#else
619#define board_mux NULL
620#endif 526#endif
621 527
622static struct omap_musb_board_data musb_board_data = {
623 .interface_type = MUSB_INTERFACE_ULPI,
624 .mode = MUSB_OTG,
625 .power = 100,
626};
627
628static void __init omap3_stalker_init(void) 528static void __init omap3_stalker_init(void)
629{ 529{
630 omap3_mux_init(board_mux, OMAP_PACKAGE_CUS); 530 omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
531 omap_board_config = omap3_stalker_config;
532 omap_board_config_size = ARRAY_SIZE(omap3_stalker_config);
631 533
632 omap3_stalker_i2c_init(); 534 omap3_stalker_i2c_init();
633 535
634 platform_add_devices(omap3_stalker_devices, 536 platform_add_devices(omap3_stalker_devices,
635 ARRAY_SIZE(omap3_stalker_devices)); 537 ARRAY_SIZE(omap3_stalker_devices));
636 538
637 spi_register_board_info(omap3stalker_spi_board_info, 539 omap_display_init(&omap3_stalker_dss_data);
638 ARRAY_SIZE(omap3stalker_spi_board_info));
639 540
640 omap_serial_init(); 541 omap_serial_init();
641 usb_musb_init(&musb_board_data); 542 usb_musb_init(NULL);
642 usb_ehci_init(&ehci_pdata); 543 usbhs_init(&usbhs_bdata);
643 ads7846_dev_init(); 544 omap_ads7846_init(1, OMAP3_STALKER_TS_GPIO, 310, NULL);
644 545
645 omap_mux_init_gpio(21, OMAP_PIN_OUTPUT); 546 omap_mux_init_gpio(21, OMAP_PIN_OUTPUT);
646 omap_mux_init_gpio(18, OMAP_PIN_INPUT_PULLUP); 547 omap_mux_init_gpio(18, OMAP_PIN_INPUT_PULLUP);
@@ -654,10 +555,9 @@ static void __init omap3_stalker_init(void)
654 555
655MACHINE_START(SBC3530, "OMAP3 STALKER") 556MACHINE_START(SBC3530, "OMAP3 STALKER")
656 /* Maintainer: Jason Lam -lzg@ema-tech.com */ 557 /* Maintainer: Jason Lam -lzg@ema-tech.com */
657 .phys_io = 0x48000000,
658 .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
659 .boot_params = 0x80000100, 558 .boot_params = 0x80000100,
660 .map_io = omap3_map_io, 559 .map_io = omap3_map_io,
560 .init_early = omap3_stalker_init_early,
661 .init_irq = omap3_stalker_init_irq, 561 .init_irq = omap3_stalker_init_irq,
662 .init_machine = omap3_stalker_init, 562 .init_machine = omap3_stalker_init,
663 .timer = &omap_timer, 563 .timer = &omap_timer,