Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-pxa/em-x270.c
10817 views
1
/*
2
* Support for CompuLab EM-X270 platform
3
*
4
* Copyright (C) 2007, 2008 CompuLab, Ltd.
5
* Author: Mike Rapoport <[email protected]>
6
*
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License version 2 as
9
* published by the Free Software Foundation.
10
*/
11
12
#include <linux/irq.h>
13
#include <linux/platform_device.h>
14
#include <linux/delay.h>
15
16
#include <linux/dm9000.h>
17
#include <linux/rtc-v3020.h>
18
#include <linux/mtd/nand.h>
19
#include <linux/mtd/partitions.h>
20
#include <linux/mtd/physmap.h>
21
#include <linux/input.h>
22
#include <linux/gpio_keys.h>
23
#include <linux/gpio.h>
24
#include <linux/mfd/da903x.h>
25
#include <linux/regulator/machine.h>
26
#include <linux/spi/spi.h>
27
#include <linux/spi/tdo24m.h>
28
#include <linux/spi/libertas_spi.h>
29
#include <linux/spi/pxa2xx_spi.h>
30
#include <linux/power_supply.h>
31
#include <linux/apm-emulation.h>
32
#include <linux/i2c.h>
33
#include <linux/i2c/pca953x.h>
34
#include <linux/i2c/pxa-i2c.h>
35
#include <linux/regulator/userspace-consumer.h>
36
37
#include <media/soc_camera.h>
38
39
#include <asm/mach-types.h>
40
#include <asm/mach/arch.h>
41
42
#include <mach/pxa27x.h>
43
#include <mach/pxa27x-udc.h>
44
#include <mach/audio.h>
45
#include <mach/pxafb.h>
46
#include <mach/ohci.h>
47
#include <mach/mmc.h>
48
#include <plat/pxa27x_keypad.h>
49
#include <mach/camera.h>
50
51
#include "generic.h"
52
#include "devices.h"
53
54
/* EM-X270 specific GPIOs */
55
#define GPIO13_MMC_CD (13)
56
#define GPIO95_MMC_WP (95)
57
#define GPIO56_NAND_RB (56)
58
#define GPIO93_CAM_RESET (93)
59
#define GPIO16_USB_HUB_RESET (16)
60
61
/* eXeda specific GPIOs */
62
#define GPIO114_MMC_CD (114)
63
#define GPIO20_NAND_RB (20)
64
#define GPIO38_SD_PWEN (38)
65
#define GPIO37_WLAN_RST (37)
66
#define GPIO95_TOUCHPAD_INT (95)
67
#define GPIO130_CAM_RESET (130)
68
#define GPIO10_USB_HUB_RESET (10)
69
70
/* common GPIOs */
71
#define GPIO11_NAND_CS (11)
72
#define GPIO41_ETHIRQ (41)
73
#define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ)
74
#define GPIO115_WLAN_PWEN (115)
75
#define GPIO19_WLAN_STRAP (19)
76
#define GPIO9_USB_VBUS_EN (9)
77
78
static int mmc_cd;
79
static int nand_rb;
80
static int dm9000_flags;
81
static int cam_reset;
82
static int usb_hub_reset;
83
84
static unsigned long common_pin_config[] = {
85
/* AC'97 */
86
GPIO28_AC97_BITCLK,
87
GPIO29_AC97_SDATA_IN_0,
88
GPIO30_AC97_SDATA_OUT,
89
GPIO31_AC97_SYNC,
90
GPIO98_AC97_SYSCLK,
91
GPIO113_AC97_nRESET,
92
93
/* BTUART */
94
GPIO42_BTUART_RXD,
95
GPIO43_BTUART_TXD,
96
GPIO44_BTUART_CTS,
97
GPIO45_BTUART_RTS,
98
99
/* STUART */
100
GPIO46_STUART_RXD,
101
GPIO47_STUART_TXD,
102
103
/* MCI controller */
104
GPIO32_MMC_CLK,
105
GPIO112_MMC_CMD,
106
GPIO92_MMC_DAT_0,
107
GPIO109_MMC_DAT_1,
108
GPIO110_MMC_DAT_2,
109
GPIO111_MMC_DAT_3,
110
111
/* LCD */
112
GPIOxx_LCD_TFT_16BPP,
113
114
/* QCI */
115
GPIO84_CIF_FV,
116
GPIO25_CIF_LV,
117
GPIO53_CIF_MCLK,
118
GPIO54_CIF_PCLK,
119
GPIO81_CIF_DD_0,
120
GPIO55_CIF_DD_1,
121
GPIO51_CIF_DD_2,
122
GPIO50_CIF_DD_3,
123
GPIO52_CIF_DD_4,
124
GPIO48_CIF_DD_5,
125
GPIO17_CIF_DD_6,
126
GPIO12_CIF_DD_7,
127
128
/* I2C */
129
GPIO117_I2C_SCL,
130
GPIO118_I2C_SDA,
131
132
/* Keypad */
133
GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
134
GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
135
GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
136
GPIO34_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
137
GPIO39_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH,
138
GPIO99_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH,
139
GPIO91_KP_MKIN_6 | WAKEUP_ON_LEVEL_HIGH,
140
GPIO36_KP_MKIN_7 | WAKEUP_ON_LEVEL_HIGH,
141
GPIO103_KP_MKOUT_0,
142
GPIO104_KP_MKOUT_1,
143
GPIO105_KP_MKOUT_2,
144
GPIO106_KP_MKOUT_3,
145
GPIO107_KP_MKOUT_4,
146
GPIO108_KP_MKOUT_5,
147
GPIO96_KP_MKOUT_6,
148
GPIO22_KP_MKOUT_7,
149
150
/* SSP1 */
151
GPIO26_SSP1_RXD,
152
GPIO23_SSP1_SCLK,
153
GPIO24_SSP1_SFRM,
154
GPIO57_SSP1_TXD,
155
156
/* SSP2 */
157
GPIO19_GPIO, /* SSP2 clock is used as GPIO for Libertas pin-strap */
158
GPIO14_GPIO,
159
GPIO89_SSP2_TXD,
160
GPIO88_SSP2_RXD,
161
162
/* SDRAM and local bus */
163
GPIO15_nCS_1,
164
GPIO78_nCS_2,
165
GPIO79_nCS_3,
166
GPIO80_nCS_4,
167
GPIO49_nPWE,
168
GPIO18_RDY,
169
170
/* GPIO */
171
GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, /* sleep/resume button */
172
173
/* power controls */
174
GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* GPRS_PWEN */
175
GPIO115_GPIO | MFP_LPM_DRIVE_LOW, /* WLAN_PWEN */
176
177
/* NAND controls */
178
GPIO11_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */
179
180
/* interrupts */
181
GPIO41_GPIO, /* DM9000 interrupt */
182
};
183
184
static unsigned long em_x270_pin_config[] = {
185
GPIO13_GPIO, /* MMC card detect */
186
GPIO16_GPIO, /* USB hub reset */
187
GPIO56_GPIO, /* NAND Ready/Busy */
188
GPIO93_GPIO | MFP_LPM_DRIVE_LOW, /* Camera reset */
189
GPIO95_GPIO, /* MMC Write protect */
190
};
191
192
static unsigned long exeda_pin_config[] = {
193
GPIO10_GPIO, /* USB hub reset */
194
GPIO20_GPIO, /* NAND Ready/Busy */
195
GPIO38_GPIO | MFP_LPM_DRIVE_LOW, /* SD slot power */
196
GPIO95_GPIO, /* touchpad IRQ */
197
GPIO114_GPIO, /* MMC card detect */
198
};
199
200
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
201
static struct resource em_x270_dm9000_resource[] = {
202
[0] = {
203
.start = PXA_CS2_PHYS,
204
.end = PXA_CS2_PHYS + 3,
205
.flags = IORESOURCE_MEM,
206
},
207
[1] = {
208
.start = PXA_CS2_PHYS + 8,
209
.end = PXA_CS2_PHYS + 8 + 0x3f,
210
.flags = IORESOURCE_MEM,
211
},
212
[2] = {
213
.start = EM_X270_ETHIRQ,
214
.end = EM_X270_ETHIRQ,
215
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
216
}
217
};
218
219
static struct dm9000_plat_data em_x270_dm9000_platdata = {
220
.flags = DM9000_PLATF_NO_EEPROM,
221
};
222
223
static struct platform_device em_x270_dm9000 = {
224
.name = "dm9000",
225
.id = 0,
226
.num_resources = ARRAY_SIZE(em_x270_dm9000_resource),
227
.resource = em_x270_dm9000_resource,
228
.dev = {
229
.platform_data = &em_x270_dm9000_platdata,
230
}
231
};
232
233
static void __init em_x270_init_dm9000(void)
234
{
235
em_x270_dm9000_platdata.flags |= dm9000_flags;
236
platform_device_register(&em_x270_dm9000);
237
}
238
#else
239
static inline void em_x270_init_dm9000(void) {}
240
#endif
241
242
/* V3020 RTC */
243
#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
244
static struct resource em_x270_v3020_resource[] = {
245
[0] = {
246
.start = PXA_CS4_PHYS,
247
.end = PXA_CS4_PHYS + 3,
248
.flags = IORESOURCE_MEM,
249
},
250
};
251
252
static struct v3020_platform_data em_x270_v3020_platdata = {
253
.leftshift = 0,
254
};
255
256
static struct platform_device em_x270_rtc = {
257
.name = "v3020",
258
.num_resources = ARRAY_SIZE(em_x270_v3020_resource),
259
.resource = em_x270_v3020_resource,
260
.id = -1,
261
.dev = {
262
.platform_data = &em_x270_v3020_platdata,
263
}
264
};
265
266
static void __init em_x270_init_rtc(void)
267
{
268
platform_device_register(&em_x270_rtc);
269
}
270
#else
271
static inline void em_x270_init_rtc(void) {}
272
#endif
273
274
/* NAND flash */
275
#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
276
static inline void nand_cs_on(void)
277
{
278
gpio_set_value(GPIO11_NAND_CS, 0);
279
}
280
281
static void nand_cs_off(void)
282
{
283
dsb();
284
285
gpio_set_value(GPIO11_NAND_CS, 1);
286
}
287
288
/* hardware specific access to control-lines */
289
static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat,
290
unsigned int ctrl)
291
{
292
struct nand_chip *this = mtd->priv;
293
unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
294
295
dsb();
296
297
if (ctrl & NAND_CTRL_CHANGE) {
298
if (ctrl & NAND_ALE)
299
nandaddr |= (1 << 3);
300
else
301
nandaddr &= ~(1 << 3);
302
if (ctrl & NAND_CLE)
303
nandaddr |= (1 << 2);
304
else
305
nandaddr &= ~(1 << 2);
306
if (ctrl & NAND_NCE)
307
nand_cs_on();
308
else
309
nand_cs_off();
310
}
311
312
dsb();
313
this->IO_ADDR_W = (void __iomem *)nandaddr;
314
if (dat != NAND_CMD_NONE)
315
writel(dat, this->IO_ADDR_W);
316
317
dsb();
318
}
319
320
/* read device ready pin */
321
static int em_x270_nand_device_ready(struct mtd_info *mtd)
322
{
323
dsb();
324
325
return gpio_get_value(nand_rb);
326
}
327
328
static struct mtd_partition em_x270_partition_info[] = {
329
[0] = {
330
.name = "em_x270-0",
331
.offset = 0,
332
.size = SZ_4M,
333
},
334
[1] = {
335
.name = "em_x270-1",
336
.offset = MTDPART_OFS_APPEND,
337
.size = MTDPART_SIZ_FULL
338
},
339
};
340
341
static const char *em_x270_part_probes[] = { "cmdlinepart", NULL };
342
343
struct platform_nand_data em_x270_nand_platdata = {
344
.chip = {
345
.nr_chips = 1,
346
.chip_offset = 0,
347
.nr_partitions = ARRAY_SIZE(em_x270_partition_info),
348
.partitions = em_x270_partition_info,
349
.chip_delay = 20,
350
.part_probe_types = em_x270_part_probes,
351
},
352
.ctrl = {
353
.hwcontrol = 0,
354
.dev_ready = em_x270_nand_device_ready,
355
.select_chip = 0,
356
.cmd_ctrl = em_x270_nand_cmd_ctl,
357
},
358
};
359
360
static struct resource em_x270_nand_resource[] = {
361
[0] = {
362
.start = PXA_CS1_PHYS,
363
.end = PXA_CS1_PHYS + 12,
364
.flags = IORESOURCE_MEM,
365
},
366
};
367
368
static struct platform_device em_x270_nand = {
369
.name = "gen_nand",
370
.num_resources = ARRAY_SIZE(em_x270_nand_resource),
371
.resource = em_x270_nand_resource,
372
.id = -1,
373
.dev = {
374
.platform_data = &em_x270_nand_platdata,
375
}
376
};
377
378
static void __init em_x270_init_nand(void)
379
{
380
int err;
381
382
err = gpio_request(GPIO11_NAND_CS, "NAND CS");
383
if (err) {
384
pr_warning("EM-X270: failed to request NAND CS gpio\n");
385
return;
386
}
387
388
gpio_direction_output(GPIO11_NAND_CS, 1);
389
390
err = gpio_request(nand_rb, "NAND R/B");
391
if (err) {
392
pr_warning("EM-X270: failed to request NAND R/B gpio\n");
393
gpio_free(GPIO11_NAND_CS);
394
return;
395
}
396
397
gpio_direction_input(nand_rb);
398
399
platform_device_register(&em_x270_nand);
400
}
401
#else
402
static inline void em_x270_init_nand(void) {}
403
#endif
404
405
#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
406
static struct mtd_partition em_x270_nor_parts[] = {
407
{
408
.name = "Bootloader",
409
.offset = 0x00000000,
410
.size = 0x00050000,
411
.mask_flags = MTD_WRITEABLE /* force read-only */
412
}, {
413
.name = "Environment",
414
.offset = 0x00050000,
415
.size = 0x00010000,
416
}, {
417
.name = "Reserved",
418
.offset = 0x00060000,
419
.size = 0x00050000,
420
.mask_flags = MTD_WRITEABLE /* force read-only */
421
}, {
422
.name = "Splashscreen",
423
.offset = 0x000b0000,
424
.size = 0x00050000,
425
}
426
};
427
428
static struct physmap_flash_data em_x270_nor_data[] = {
429
[0] = {
430
.width = 2,
431
.parts = em_x270_nor_parts,
432
.nr_parts = ARRAY_SIZE(em_x270_nor_parts),
433
},
434
};
435
436
static struct resource em_x270_nor_flash_resource = {
437
.start = PXA_CS0_PHYS,
438
.end = PXA_CS0_PHYS + SZ_1M - 1,
439
.flags = IORESOURCE_MEM,
440
};
441
442
static struct platform_device em_x270_physmap_flash = {
443
.name = "physmap-flash",
444
.id = 0,
445
.num_resources = 1,
446
.resource = &em_x270_nor_flash_resource,
447
.dev = {
448
.platform_data = &em_x270_nor_data,
449
},
450
};
451
452
static void __init em_x270_init_nor(void)
453
{
454
platform_device_register(&em_x270_physmap_flash);
455
}
456
#else
457
static inline void em_x270_init_nor(void) {}
458
#endif
459
460
/* PXA27x OHCI controller setup */
461
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
462
static struct regulator *em_x270_usb_ldo;
463
464
static int em_x270_usb_hub_init(void)
465
{
466
int err;
467
468
em_x270_usb_ldo = regulator_get(NULL, "vcc usb");
469
if (IS_ERR(em_x270_usb_ldo))
470
return PTR_ERR(em_x270_usb_ldo);
471
472
err = gpio_request(GPIO9_USB_VBUS_EN, "vbus en");
473
if (err)
474
goto err_free_usb_ldo;
475
476
err = gpio_request(usb_hub_reset, "hub rst");
477
if (err)
478
goto err_free_vbus_gpio;
479
480
/* USB Hub power-on and reset */
481
gpio_direction_output(usb_hub_reset, 1);
482
gpio_direction_output(GPIO9_USB_VBUS_EN, 0);
483
regulator_enable(em_x270_usb_ldo);
484
gpio_set_value(usb_hub_reset, 0);
485
gpio_set_value(usb_hub_reset, 1);
486
regulator_disable(em_x270_usb_ldo);
487
regulator_enable(em_x270_usb_ldo);
488
gpio_set_value(usb_hub_reset, 0);
489
gpio_set_value(GPIO9_USB_VBUS_EN, 1);
490
491
return 0;
492
493
err_free_vbus_gpio:
494
gpio_free(GPIO9_USB_VBUS_EN);
495
err_free_usb_ldo:
496
regulator_put(em_x270_usb_ldo);
497
498
return err;
499
}
500
501
static int em_x270_ohci_init(struct device *dev)
502
{
503
int err;
504
505
/* we don't want to entirely disable USB if the HUB init failed */
506
err = em_x270_usb_hub_init();
507
if (err)
508
pr_err("USB Hub initialization failed: %d\n", err);
509
510
/* enable port 2 transiever */
511
UP2OCR = UP2OCR_HXS | UP2OCR_HXOE;
512
513
return 0;
514
}
515
516
static void em_x270_ohci_exit(struct device *dev)
517
{
518
gpio_free(usb_hub_reset);
519
gpio_free(GPIO9_USB_VBUS_EN);
520
521
if (!IS_ERR(em_x270_usb_ldo)) {
522
if (regulator_is_enabled(em_x270_usb_ldo))
523
regulator_disable(em_x270_usb_ldo);
524
525
regulator_put(em_x270_usb_ldo);
526
}
527
}
528
529
static struct pxaohci_platform_data em_x270_ohci_platform_data = {
530
.port_mode = PMM_PERPORT_MODE,
531
.flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW,
532
.init = em_x270_ohci_init,
533
.exit = em_x270_ohci_exit,
534
};
535
536
static void __init em_x270_init_ohci(void)
537
{
538
pxa_set_ohci_info(&em_x270_ohci_platform_data);
539
}
540
#else
541
static inline void em_x270_init_ohci(void) {}
542
#endif
543
544
/* MCI controller setup */
545
#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
546
static struct regulator *em_x270_sdio_ldo;
547
548
static int em_x270_mci_init(struct device *dev,
549
irq_handler_t em_x270_detect_int,
550
void *data)
551
{
552
int err;
553
554
em_x270_sdio_ldo = regulator_get(dev, "vcc sdio");
555
if (IS_ERR(em_x270_sdio_ldo)) {
556
dev_err(dev, "can't request SDIO power supply: %ld\n",
557
PTR_ERR(em_x270_sdio_ldo));
558
return PTR_ERR(em_x270_sdio_ldo);
559
}
560
561
err = request_irq(gpio_to_irq(mmc_cd), em_x270_detect_int,
562
IRQF_DISABLED | IRQF_TRIGGER_RISING |
563
IRQF_TRIGGER_FALLING,
564
"MMC card detect", data);
565
if (err) {
566
dev_err(dev, "can't request MMC card detect IRQ: %d\n", err);
567
goto err_irq;
568
}
569
570
if (machine_is_em_x270()) {
571
err = gpio_request(GPIO95_MMC_WP, "MMC WP");
572
if (err) {
573
dev_err(dev, "can't request MMC write protect: %d\n",
574
err);
575
goto err_gpio_wp;
576
}
577
gpio_direction_input(GPIO95_MMC_WP);
578
} else {
579
err = gpio_request(GPIO38_SD_PWEN, "sdio power");
580
if (err) {
581
dev_err(dev, "can't request MMC power control : %d\n",
582
err);
583
goto err_gpio_wp;
584
}
585
gpio_direction_output(GPIO38_SD_PWEN, 1);
586
}
587
588
return 0;
589
590
err_gpio_wp:
591
free_irq(gpio_to_irq(mmc_cd), data);
592
err_irq:
593
regulator_put(em_x270_sdio_ldo);
594
595
return err;
596
}
597
598
static void em_x270_mci_setpower(struct device *dev, unsigned int vdd)
599
{
600
struct pxamci_platform_data* p_d = dev->platform_data;
601
602
if ((1 << vdd) & p_d->ocr_mask) {
603
int vdd_uV = (2000 + (vdd - __ffs(MMC_VDD_20_21)) * 100) * 1000;
604
605
regulator_set_voltage(em_x270_sdio_ldo, vdd_uV, vdd_uV);
606
regulator_enable(em_x270_sdio_ldo);
607
} else {
608
regulator_disable(em_x270_sdio_ldo);
609
}
610
}
611
612
static void em_x270_mci_exit(struct device *dev, void *data)
613
{
614
free_irq(gpio_to_irq(mmc_cd), data);
615
regulator_put(em_x270_sdio_ldo);
616
617
if (machine_is_em_x270())
618
gpio_free(GPIO95_MMC_WP);
619
else
620
gpio_free(GPIO38_SD_PWEN);
621
}
622
623
static int em_x270_mci_get_ro(struct device *dev)
624
{
625
return gpio_get_value(GPIO95_MMC_WP);
626
}
627
628
static struct pxamci_platform_data em_x270_mci_platform_data = {
629
.detect_delay_ms = 250,
630
.ocr_mask = MMC_VDD_20_21|MMC_VDD_21_22|MMC_VDD_22_23|
631
MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27|
632
MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|
633
MMC_VDD_30_31|MMC_VDD_31_32,
634
.init = em_x270_mci_init,
635
.setpower = em_x270_mci_setpower,
636
.exit = em_x270_mci_exit,
637
.gpio_card_detect = -1,
638
.gpio_card_ro = -1,
639
.gpio_power = -1,
640
};
641
642
static void __init em_x270_init_mmc(void)
643
{
644
if (machine_is_em_x270())
645
em_x270_mci_platform_data.get_ro = em_x270_mci_get_ro;
646
647
pxa_set_mci_info(&em_x270_mci_platform_data);
648
}
649
#else
650
static inline void em_x270_init_mmc(void) {}
651
#endif
652
653
/* LCD */
654
#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE)
655
static struct pxafb_mode_info em_x270_lcd_modes[] = {
656
[0] = {
657
.pixclock = 38250,
658
.bpp = 16,
659
.xres = 480,
660
.yres = 640,
661
.hsync_len = 8,
662
.vsync_len = 2,
663
.left_margin = 8,
664
.upper_margin = 2,
665
.right_margin = 24,
666
.lower_margin = 4,
667
.sync = 0,
668
},
669
[1] = {
670
.pixclock = 153800,
671
.bpp = 16,
672
.xres = 240,
673
.yres = 320,
674
.hsync_len = 8,
675
.vsync_len = 2,
676
.left_margin = 8,
677
.upper_margin = 2,
678
.right_margin = 88,
679
.lower_margin = 2,
680
.sync = 0,
681
},
682
};
683
684
static struct pxafb_mach_info em_x270_lcd = {
685
.modes = em_x270_lcd_modes,
686
.num_modes = 2,
687
.lcd_conn = LCD_COLOR_TFT_16BPP,
688
};
689
690
static void __init em_x270_init_lcd(void)
691
{
692
pxa_set_fb_info(NULL, &em_x270_lcd);
693
}
694
#else
695
static inline void em_x270_init_lcd(void) {}
696
#endif
697
698
#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
699
static struct pxa2xx_spi_master em_x270_spi_info = {
700
.num_chipselect = 1,
701
};
702
703
static struct pxa2xx_spi_chip em_x270_tdo24m_chip = {
704
.rx_threshold = 1,
705
.tx_threshold = 1,
706
.gpio_cs = -1,
707
};
708
709
static struct tdo24m_platform_data em_x270_tdo24m_pdata = {
710
.model = TDO35S,
711
};
712
713
static struct pxa2xx_spi_master em_x270_spi_2_info = {
714
.num_chipselect = 1,
715
.enable_dma = 1,
716
};
717
718
static struct pxa2xx_spi_chip em_x270_libertas_chip = {
719
.rx_threshold = 1,
720
.tx_threshold = 1,
721
.timeout = 1000,
722
.gpio_cs = 14,
723
};
724
725
static unsigned long em_x270_libertas_pin_config[] = {
726
/* SSP2 */
727
GPIO19_SSP2_SCLK,
728
GPIO14_GPIO,
729
GPIO89_SSP2_TXD,
730
GPIO88_SSP2_RXD,
731
};
732
733
static int em_x270_libertas_setup(struct spi_device *spi)
734
{
735
int err = gpio_request(GPIO115_WLAN_PWEN, "WLAN PWEN");
736
if (err)
737
return err;
738
739
err = gpio_request(GPIO19_WLAN_STRAP, "WLAN STRAP");
740
if (err)
741
goto err_free_pwen;
742
743
if (machine_is_exeda()) {
744
err = gpio_request(GPIO37_WLAN_RST, "WLAN RST");
745
if (err)
746
goto err_free_strap;
747
748
gpio_direction_output(GPIO37_WLAN_RST, 1);
749
msleep(100);
750
}
751
752
gpio_direction_output(GPIO19_WLAN_STRAP, 1);
753
msleep(100);
754
755
pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_libertas_pin_config));
756
757
gpio_direction_output(GPIO115_WLAN_PWEN, 0);
758
msleep(100);
759
gpio_set_value(GPIO115_WLAN_PWEN, 1);
760
msleep(100);
761
762
spi->bits_per_word = 16;
763
spi_setup(spi);
764
765
return 0;
766
767
err_free_strap:
768
gpio_free(GPIO19_WLAN_STRAP);
769
err_free_pwen:
770
gpio_free(GPIO115_WLAN_PWEN);
771
772
return err;
773
}
774
775
static int em_x270_libertas_teardown(struct spi_device *spi)
776
{
777
gpio_set_value(GPIO115_WLAN_PWEN, 0);
778
gpio_free(GPIO115_WLAN_PWEN);
779
gpio_free(GPIO19_WLAN_STRAP);
780
781
if (machine_is_exeda()) {
782
gpio_set_value(GPIO37_WLAN_RST, 0);
783
gpio_free(GPIO37_WLAN_RST);
784
}
785
786
return 0;
787
}
788
789
struct libertas_spi_platform_data em_x270_libertas_pdata = {
790
.use_dummy_writes = 1,
791
.setup = em_x270_libertas_setup,
792
.teardown = em_x270_libertas_teardown,
793
};
794
795
static struct spi_board_info em_x270_spi_devices[] __initdata = {
796
{
797
.modalias = "tdo24m",
798
.max_speed_hz = 1000000,
799
.bus_num = 1,
800
.chip_select = 0,
801
.controller_data = &em_x270_tdo24m_chip,
802
.platform_data = &em_x270_tdo24m_pdata,
803
},
804
{
805
.modalias = "libertas_spi",
806
.max_speed_hz = 13000000,
807
.bus_num = 2,
808
.irq = IRQ_GPIO(116),
809
.chip_select = 0,
810
.controller_data = &em_x270_libertas_chip,
811
.platform_data = &em_x270_libertas_pdata,
812
},
813
};
814
815
static void __init em_x270_init_spi(void)
816
{
817
pxa2xx_set_spi_info(1, &em_x270_spi_info);
818
pxa2xx_set_spi_info(2, &em_x270_spi_2_info);
819
spi_register_board_info(ARRAY_AND_SIZE(em_x270_spi_devices));
820
}
821
#else
822
static inline void em_x270_init_spi(void) {}
823
#endif
824
825
#if defined(CONFIG_SND_PXA2XX_LIB_AC97)
826
static pxa2xx_audio_ops_t em_x270_ac97_info = {
827
.reset_gpio = 113,
828
};
829
830
static void __init em_x270_init_ac97(void)
831
{
832
pxa_set_ac97_info(&em_x270_ac97_info);
833
}
834
#else
835
static inline void em_x270_init_ac97(void) {}
836
#endif
837
838
#if defined(CONFIG_KEYBOARD_PXA27x) || defined(CONFIG_KEYBOARD_PXA27x_MODULE)
839
static unsigned int em_x270_module_matrix_keys[] = {
840
KEY(0, 0, KEY_A), KEY(1, 0, KEY_UP), KEY(2, 1, KEY_B),
841
KEY(0, 2, KEY_LEFT), KEY(1, 1, KEY_ENTER), KEY(2, 0, KEY_RIGHT),
842
KEY(0, 1, KEY_C), KEY(1, 2, KEY_DOWN), KEY(2, 2, KEY_D),
843
};
844
845
struct pxa27x_keypad_platform_data em_x270_module_keypad_info = {
846
/* code map for the matrix keys */
847
.matrix_key_rows = 3,
848
.matrix_key_cols = 3,
849
.matrix_key_map = em_x270_module_matrix_keys,
850
.matrix_key_map_size = ARRAY_SIZE(em_x270_module_matrix_keys),
851
};
852
853
static unsigned int em_x270_exeda_matrix_keys[] = {
854
KEY(0, 0, KEY_RIGHTSHIFT), KEY(0, 1, KEY_RIGHTCTRL),
855
KEY(0, 2, KEY_RIGHTALT), KEY(0, 3, KEY_SPACE),
856
KEY(0, 4, KEY_LEFTALT), KEY(0, 5, KEY_LEFTCTRL),
857
KEY(0, 6, KEY_ENTER), KEY(0, 7, KEY_SLASH),
858
859
KEY(1, 0, KEY_DOT), KEY(1, 1, KEY_M),
860
KEY(1, 2, KEY_N), KEY(1, 3, KEY_B),
861
KEY(1, 4, KEY_V), KEY(1, 5, KEY_C),
862
KEY(1, 6, KEY_X), KEY(1, 7, KEY_Z),
863
864
KEY(2, 0, KEY_LEFTSHIFT), KEY(2, 1, KEY_SEMICOLON),
865
KEY(2, 2, KEY_L), KEY(2, 3, KEY_K),
866
KEY(2, 4, KEY_J), KEY(2, 5, KEY_H),
867
KEY(2, 6, KEY_G), KEY(2, 7, KEY_F),
868
869
KEY(3, 0, KEY_D), KEY(3, 1, KEY_S),
870
KEY(3, 2, KEY_A), KEY(3, 3, KEY_TAB),
871
KEY(3, 4, KEY_BACKSPACE), KEY(3, 5, KEY_P),
872
KEY(3, 6, KEY_O), KEY(3, 7, KEY_I),
873
874
KEY(4, 0, KEY_U), KEY(4, 1, KEY_Y),
875
KEY(4, 2, KEY_T), KEY(4, 3, KEY_R),
876
KEY(4, 4, KEY_E), KEY(4, 5, KEY_W),
877
KEY(4, 6, KEY_Q), KEY(4, 7, KEY_MINUS),
878
879
KEY(5, 0, KEY_0), KEY(5, 1, KEY_9),
880
KEY(5, 2, KEY_8), KEY(5, 3, KEY_7),
881
KEY(5, 4, KEY_6), KEY(5, 5, KEY_5),
882
KEY(5, 6, KEY_4), KEY(5, 7, KEY_3),
883
884
KEY(6, 0, KEY_2), KEY(6, 1, KEY_1),
885
KEY(6, 2, KEY_ENTER), KEY(6, 3, KEY_END),
886
KEY(6, 4, KEY_DOWN), KEY(6, 5, KEY_UP),
887
KEY(6, 6, KEY_MENU), KEY(6, 7, KEY_F1),
888
889
KEY(7, 0, KEY_LEFT), KEY(7, 1, KEY_RIGHT),
890
KEY(7, 2, KEY_BACK), KEY(7, 3, KEY_HOME),
891
KEY(7, 4, 0), KEY(7, 5, 0),
892
KEY(7, 6, 0), KEY(7, 7, 0),
893
};
894
895
struct pxa27x_keypad_platform_data em_x270_exeda_keypad_info = {
896
/* code map for the matrix keys */
897
.matrix_key_rows = 8,
898
.matrix_key_cols = 8,
899
.matrix_key_map = em_x270_exeda_matrix_keys,
900
.matrix_key_map_size = ARRAY_SIZE(em_x270_exeda_matrix_keys),
901
};
902
903
static void __init em_x270_init_keypad(void)
904
{
905
if (machine_is_em_x270())
906
pxa_set_keypad_info(&em_x270_module_keypad_info);
907
else
908
pxa_set_keypad_info(&em_x270_exeda_keypad_info);
909
}
910
#else
911
static inline void em_x270_init_keypad(void) {}
912
#endif
913
914
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
915
static struct gpio_keys_button gpio_keys_button[] = {
916
[0] = {
917
.desc = "sleep/wakeup",
918
.code = KEY_SUSPEND,
919
.type = EV_PWR,
920
.gpio = 1,
921
.wakeup = 1,
922
},
923
};
924
925
static struct gpio_keys_platform_data em_x270_gpio_keys_data = {
926
.buttons = gpio_keys_button,
927
.nbuttons = 1,
928
};
929
930
static struct platform_device em_x270_gpio_keys = {
931
.name = "gpio-keys",
932
.id = -1,
933
.dev = {
934
.platform_data = &em_x270_gpio_keys_data,
935
},
936
};
937
938
static void __init em_x270_init_gpio_keys(void)
939
{
940
platform_device_register(&em_x270_gpio_keys);
941
}
942
#else
943
static inline void em_x270_init_gpio_keys(void) {}
944
#endif
945
946
/* Quick Capture Interface and sensor setup */
947
#if defined(CONFIG_VIDEO_PXA27x) || defined(CONFIG_VIDEO_PXA27x_MODULE)
948
static struct regulator *em_x270_camera_ldo;
949
950
static int em_x270_sensor_init(void)
951
{
952
int ret;
953
954
ret = gpio_request(cam_reset, "camera reset");
955
if (ret)
956
return ret;
957
958
gpio_direction_output(cam_reset, 0);
959
960
em_x270_camera_ldo = regulator_get(NULL, "vcc cam");
961
if (em_x270_camera_ldo == NULL) {
962
gpio_free(cam_reset);
963
return -ENODEV;
964
}
965
966
ret = regulator_enable(em_x270_camera_ldo);
967
if (ret) {
968
regulator_put(em_x270_camera_ldo);
969
gpio_free(cam_reset);
970
return ret;
971
}
972
973
gpio_set_value(cam_reset, 1);
974
975
return 0;
976
}
977
978
struct pxacamera_platform_data em_x270_camera_platform_data = {
979
.flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
980
PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
981
.mclk_10khz = 2600,
982
};
983
984
static int em_x270_sensor_power(struct device *dev, int on)
985
{
986
int ret;
987
int is_on = regulator_is_enabled(em_x270_camera_ldo);
988
989
if (on == is_on)
990
return 0;
991
992
gpio_set_value(cam_reset, !on);
993
994
if (on)
995
ret = regulator_enable(em_x270_camera_ldo);
996
else
997
ret = regulator_disable(em_x270_camera_ldo);
998
999
if (ret)
1000
return ret;
1001
1002
gpio_set_value(cam_reset, on);
1003
1004
return 0;
1005
}
1006
1007
static struct i2c_board_info em_x270_i2c_cam_info[] = {
1008
{
1009
I2C_BOARD_INFO("mt9m111", 0x48),
1010
},
1011
};
1012
1013
static struct soc_camera_link iclink = {
1014
.bus_id = 0,
1015
.power = em_x270_sensor_power,
1016
.board_info = &em_x270_i2c_cam_info[0],
1017
.i2c_adapter_id = 0,
1018
};
1019
1020
static struct platform_device em_x270_camera = {
1021
.name = "soc-camera-pdrv",
1022
.id = -1,
1023
.dev = {
1024
.platform_data = &iclink,
1025
},
1026
};
1027
1028
static void __init em_x270_init_camera(void)
1029
{
1030
if (em_x270_sensor_init() == 0) {
1031
pxa_set_camera_info(&em_x270_camera_platform_data);
1032
platform_device_register(&em_x270_camera);
1033
}
1034
}
1035
#else
1036
static inline void em_x270_init_camera(void) {}
1037
#endif
1038
1039
static struct regulator_bulk_data em_x270_gps_consumer_supply = {
1040
.supply = "vcc gps",
1041
};
1042
1043
static struct regulator_userspace_consumer_data em_x270_gps_consumer_data = {
1044
.name = "vcc gps",
1045
.num_supplies = 1,
1046
.supplies = &em_x270_gps_consumer_supply,
1047
};
1048
1049
static struct platform_device em_x270_gps_userspace_consumer = {
1050
.name = "reg-userspace-consumer",
1051
.id = 0,
1052
.dev = {
1053
.platform_data = &em_x270_gps_consumer_data,
1054
},
1055
};
1056
1057
static struct regulator_bulk_data em_x270_gprs_consumer_supply = {
1058
.supply = "vcc gprs",
1059
};
1060
1061
static struct regulator_userspace_consumer_data em_x270_gprs_consumer_data = {
1062
.name = "vcc gprs",
1063
.num_supplies = 1,
1064
.supplies = &em_x270_gprs_consumer_supply
1065
};
1066
1067
static struct platform_device em_x270_gprs_userspace_consumer = {
1068
.name = "reg-userspace-consumer",
1069
.id = 1,
1070
.dev = {
1071
.platform_data = &em_x270_gprs_consumer_data,
1072
}
1073
};
1074
1075
static struct platform_device *em_x270_userspace_consumers[] = {
1076
&em_x270_gps_userspace_consumer,
1077
&em_x270_gprs_userspace_consumer,
1078
};
1079
1080
static void __init em_x270_userspace_consumers_init(void)
1081
{
1082
platform_add_devices(ARRAY_AND_SIZE(em_x270_userspace_consumers));
1083
}
1084
1085
/* DA9030 related initializations */
1086
#define REGULATOR_CONSUMER(_name, _dev, _supply) \
1087
static struct regulator_consumer_supply _name##_consumers[] = { \
1088
{ \
1089
.dev = _dev, \
1090
.supply = _supply, \
1091
}, \
1092
}
1093
1094
REGULATOR_CONSUMER(ldo3, &em_x270_gps_userspace_consumer.dev, "vcc gps");
1095
REGULATOR_CONSUMER(ldo5, NULL, "vcc cam");
1096
REGULATOR_CONSUMER(ldo10, &pxa_device_mci.dev, "vcc sdio");
1097
REGULATOR_CONSUMER(ldo12, NULL, "vcc usb");
1098
REGULATOR_CONSUMER(ldo19, &em_x270_gprs_userspace_consumer.dev, "vcc gprs");
1099
REGULATOR_CONSUMER(buck2, NULL, "vcc_core");
1100
1101
#define REGULATOR_INIT(_ldo, _min_uV, _max_uV, _ops_mask) \
1102
static struct regulator_init_data _ldo##_data = { \
1103
.constraints = { \
1104
.min_uV = _min_uV, \
1105
.max_uV = _max_uV, \
1106
.state_mem = { \
1107
.enabled = 0, \
1108
}, \
1109
.valid_ops_mask = _ops_mask, \
1110
.apply_uV = 1, \
1111
}, \
1112
.num_consumer_supplies = ARRAY_SIZE(_ldo##_consumers), \
1113
.consumer_supplies = _ldo##_consumers, \
1114
};
1115
1116
REGULATOR_INIT(ldo3, 3200000, 3200000, REGULATOR_CHANGE_STATUS);
1117
REGULATOR_INIT(ldo5, 3000000, 3000000, REGULATOR_CHANGE_STATUS);
1118
REGULATOR_INIT(ldo10, 2000000, 3200000,
1119
REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE);
1120
REGULATOR_INIT(ldo12, 3000000, 3000000, REGULATOR_CHANGE_STATUS);
1121
REGULATOR_INIT(ldo19, 3200000, 3200000, REGULATOR_CHANGE_STATUS);
1122
REGULATOR_INIT(buck2, 1000000, 1650000, REGULATOR_CHANGE_VOLTAGE);
1123
1124
struct led_info em_x270_led_info = {
1125
.name = "em-x270:orange",
1126
.default_trigger = "battery-charging-or-full",
1127
};
1128
1129
struct power_supply_info em_x270_psy_info = {
1130
.name = "battery",
1131
.technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
1132
.voltage_max_design = 4200000,
1133
.voltage_min_design = 3000000,
1134
.use_for_apm = 1,
1135
};
1136
1137
static void em_x270_battery_low(void)
1138
{
1139
#if defined(CONFIG_APM_EMULATION)
1140
apm_queue_event(APM_LOW_BATTERY);
1141
#endif
1142
}
1143
1144
static void em_x270_battery_critical(void)
1145
{
1146
#if defined(CONFIG_APM_EMULATION)
1147
apm_queue_event(APM_CRITICAL_SUSPEND);
1148
#endif
1149
}
1150
1151
struct da9030_battery_info em_x270_batterty_info = {
1152
.battery_info = &em_x270_psy_info,
1153
1154
.charge_milliamp = 1000,
1155
.charge_millivolt = 4200,
1156
1157
.vbat_low = 3600,
1158
.vbat_crit = 3400,
1159
.vbat_charge_start = 4100,
1160
.vbat_charge_stop = 4200,
1161
.vbat_charge_restart = 4000,
1162
1163
.vcharge_min = 3200,
1164
.vcharge_max = 5500,
1165
1166
.tbat_low = 197,
1167
.tbat_high = 78,
1168
.tbat_restart = 100,
1169
1170
.batmon_interval = 0,
1171
1172
.battery_low = em_x270_battery_low,
1173
.battery_critical = em_x270_battery_critical,
1174
};
1175
1176
#define DA9030_SUBDEV(_name, _id, _pdata) \
1177
{ \
1178
.name = "da903x-" #_name, \
1179
.id = DA9030_ID_##_id, \
1180
.platform_data = _pdata, \
1181
}
1182
1183
#define DA9030_LDO(num) DA9030_SUBDEV(regulator, LDO##num, &ldo##num##_data)
1184
1185
struct da903x_subdev_info em_x270_da9030_subdevs[] = {
1186
DA9030_LDO(3),
1187
DA9030_LDO(5),
1188
DA9030_LDO(10),
1189
DA9030_LDO(12),
1190
DA9030_LDO(19),
1191
1192
DA9030_SUBDEV(regulator, BUCK2, &buck2_data),
1193
1194
DA9030_SUBDEV(led, LED_PC, &em_x270_led_info),
1195
DA9030_SUBDEV(backlight, WLED, &em_x270_led_info),
1196
DA9030_SUBDEV(battery, BAT, &em_x270_batterty_info),
1197
};
1198
1199
static struct da903x_platform_data em_x270_da9030_info = {
1200
.num_subdevs = ARRAY_SIZE(em_x270_da9030_subdevs),
1201
.subdevs = em_x270_da9030_subdevs,
1202
};
1203
1204
static struct i2c_board_info em_x270_i2c_pmic_info = {
1205
I2C_BOARD_INFO("da9030", 0x49),
1206
.irq = IRQ_GPIO(0),
1207
.platform_data = &em_x270_da9030_info,
1208
};
1209
1210
static struct i2c_pxa_platform_data em_x270_pwr_i2c_info = {
1211
.use_pio = 1,
1212
};
1213
1214
static void __init em_x270_init_da9030(void)
1215
{
1216
pxa27x_set_i2c_power_info(&em_x270_pwr_i2c_info);
1217
i2c_register_board_info(1, &em_x270_i2c_pmic_info, 1);
1218
}
1219
1220
static struct pca953x_platform_data exeda_gpio_ext_pdata = {
1221
.gpio_base = 128,
1222
};
1223
1224
static struct i2c_board_info exeda_i2c_info[] = {
1225
{
1226
I2C_BOARD_INFO("pca9555", 0x21),
1227
.platform_data = &exeda_gpio_ext_pdata,
1228
},
1229
};
1230
1231
static struct i2c_pxa_platform_data em_x270_i2c_info = {
1232
.fast_mode = 1,
1233
};
1234
1235
static void __init em_x270_init_i2c(void)
1236
{
1237
pxa_set_i2c_info(&em_x270_i2c_info);
1238
1239
if (machine_is_exeda())
1240
i2c_register_board_info(0, ARRAY_AND_SIZE(exeda_i2c_info));
1241
}
1242
1243
static void __init em_x270_module_init(void)
1244
{
1245
pxa2xx_mfp_config(ARRAY_AND_SIZE(em_x270_pin_config));
1246
1247
mmc_cd = GPIO13_MMC_CD;
1248
nand_rb = GPIO56_NAND_RB;
1249
dm9000_flags = DM9000_PLATF_32BITONLY;
1250
cam_reset = GPIO93_CAM_RESET;
1251
usb_hub_reset = GPIO16_USB_HUB_RESET;
1252
}
1253
1254
static void __init em_x270_exeda_init(void)
1255
{
1256
pxa2xx_mfp_config(ARRAY_AND_SIZE(exeda_pin_config));
1257
1258
mmc_cd = GPIO114_MMC_CD;
1259
nand_rb = GPIO20_NAND_RB;
1260
dm9000_flags = DM9000_PLATF_16BITONLY;
1261
cam_reset = GPIO130_CAM_RESET;
1262
usb_hub_reset = GPIO10_USB_HUB_RESET;
1263
}
1264
1265
static void __init em_x270_init(void)
1266
{
1267
pxa2xx_mfp_config(ARRAY_AND_SIZE(common_pin_config));
1268
1269
pxa_set_ffuart_info(NULL);
1270
pxa_set_btuart_info(NULL);
1271
pxa_set_stuart_info(NULL);
1272
1273
#ifdef CONFIG_PM
1274
pxa27x_set_pwrmode(PWRMODE_DEEPSLEEP);
1275
#endif
1276
1277
if (machine_is_em_x270())
1278
em_x270_module_init();
1279
else if (machine_is_exeda())
1280
em_x270_exeda_init();
1281
else
1282
panic("Unsupported machine: %d\n", machine_arch_type);
1283
1284
em_x270_init_da9030();
1285
em_x270_init_dm9000();
1286
em_x270_init_rtc();
1287
em_x270_init_nand();
1288
em_x270_init_nor();
1289
em_x270_init_lcd();
1290
em_x270_init_mmc();
1291
em_x270_init_ohci();
1292
em_x270_init_keypad();
1293
em_x270_init_gpio_keys();
1294
em_x270_init_ac97();
1295
em_x270_init_spi();
1296
em_x270_init_i2c();
1297
em_x270_init_camera();
1298
em_x270_userspace_consumers_init();
1299
}
1300
1301
MACHINE_START(EM_X270, "Compulab EM-X270")
1302
.boot_params = 0xa0000100,
1303
.map_io = pxa27x_map_io,
1304
.init_irq = pxa27x_init_irq,
1305
.timer = &pxa_timer,
1306
.init_machine = em_x270_init,
1307
MACHINE_END
1308
1309
MACHINE_START(EXEDA, "Compulab eXeda")
1310
.boot_params = 0xa0000100,
1311
.map_io = pxa27x_map_io,
1312
.init_irq = pxa27x_init_irq,
1313
.timer = &pxa_timer,
1314
.init_machine = em_x270_init,
1315
MACHINE_END
1316
1317