Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/arm/mach-orion5x/net2big-setup.c
26292 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* arch/arm/mach-orion5x/net2big-setup.c
4
*
5
* LaCie 2Big Network NAS setup
6
*
7
* Copyright (C) 2009 Simon Guinot <[email protected]>
8
*/
9
10
#include <linux/kernel.h>
11
#include <linux/init.h>
12
#include <linux/platform_device.h>
13
#include <linux/mtd/physmap.h>
14
#include <linux/mv643xx_eth.h>
15
#include <linux/leds.h>
16
#include <linux/gpio_keys.h>
17
#include <linux/input.h>
18
#include <linux/i2c.h>
19
#include <linux/ata_platform.h>
20
#include <linux/gpio.h>
21
#include <linux/gpio/machine.h>
22
#include <linux/delay.h>
23
#include <asm/mach-types.h>
24
#include <asm/mach/arch.h>
25
#include <plat/orion-gpio.h>
26
#include "common.h"
27
#include "mpp.h"
28
#include "orion5x.h"
29
30
/*****************************************************************************
31
* LaCie 2Big Network Info
32
****************************************************************************/
33
34
/*
35
* 512KB NOR flash Device bus boot chip select
36
*/
37
38
#define NET2BIG_NOR_BOOT_BASE 0xfff80000
39
#define NET2BIG_NOR_BOOT_SIZE SZ_512K
40
41
/*****************************************************************************
42
* 512KB NOR Flash on Boot Device
43
****************************************************************************/
44
45
/*
46
* TODO: Check write support on flash MX29LV400CBTC-70G
47
*/
48
49
static struct mtd_partition net2big_partitions[] = {
50
{
51
.name = "Full512kb",
52
.size = MTDPART_SIZ_FULL,
53
.offset = 0x00000000,
54
.mask_flags = MTD_WRITEABLE,
55
},
56
};
57
58
static struct physmap_flash_data net2big_nor_flash_data = {
59
.width = 1,
60
.parts = net2big_partitions,
61
.nr_parts = ARRAY_SIZE(net2big_partitions),
62
};
63
64
static struct resource net2big_nor_flash_resource = {
65
.flags = IORESOURCE_MEM,
66
.start = NET2BIG_NOR_BOOT_BASE,
67
.end = NET2BIG_NOR_BOOT_BASE
68
+ NET2BIG_NOR_BOOT_SIZE - 1,
69
};
70
71
static struct platform_device net2big_nor_flash = {
72
.name = "physmap-flash",
73
.id = 0,
74
.dev = {
75
.platform_data = &net2big_nor_flash_data,
76
},
77
.num_resources = 1,
78
.resource = &net2big_nor_flash_resource,
79
};
80
81
/*****************************************************************************
82
* Ethernet
83
****************************************************************************/
84
85
static struct mv643xx_eth_platform_data net2big_eth_data = {
86
.phy_addr = MV643XX_ETH_PHY_ADDR(8),
87
};
88
89
/*****************************************************************************
90
* I2C devices
91
****************************************************************************/
92
93
/*
94
* i2c addr | chip | description
95
* 0x32 | Ricoh 5C372b | RTC
96
* 0x50 | HT24LC08 | eeprom (1kB)
97
*/
98
static struct i2c_board_info __initdata net2big_i2c_devices[] = {
99
{
100
I2C_BOARD_INFO("rs5c372b", 0x32),
101
}, {
102
I2C_BOARD_INFO("24c08", 0x50),
103
},
104
};
105
106
/*****************************************************************************
107
* SATA
108
****************************************************************************/
109
110
static struct mv_sata_platform_data net2big_sata_data = {
111
.n_ports = 2,
112
};
113
114
#define NET2BIG_GPIO_SATA_POWER_REQ 19
115
#define NET2BIG_GPIO_SATA0_POWER 23
116
#define NET2BIG_GPIO_SATA1_POWER 25
117
118
static void __init net2big_sata_power_init(void)
119
{
120
int err;
121
122
/* Configure GPIOs over MPP max number. */
123
orion_gpio_set_valid(NET2BIG_GPIO_SATA0_POWER, 1);
124
orion_gpio_set_valid(NET2BIG_GPIO_SATA1_POWER, 1);
125
126
err = gpio_request(NET2BIG_GPIO_SATA0_POWER, "SATA0 power status");
127
if (err == 0) {
128
err = gpio_direction_input(NET2BIG_GPIO_SATA0_POWER);
129
if (err)
130
gpio_free(NET2BIG_GPIO_SATA0_POWER);
131
}
132
if (err) {
133
pr_err("net2big: failed to setup SATA0 power GPIO\n");
134
return;
135
}
136
137
err = gpio_request(NET2BIG_GPIO_SATA1_POWER, "SATA1 power status");
138
if (err == 0) {
139
err = gpio_direction_input(NET2BIG_GPIO_SATA1_POWER);
140
if (err)
141
gpio_free(NET2BIG_GPIO_SATA1_POWER);
142
}
143
if (err) {
144
pr_err("net2big: failed to setup SATA1 power GPIO\n");
145
goto err_free_1;
146
}
147
148
err = gpio_request(NET2BIG_GPIO_SATA_POWER_REQ, "SATA power request");
149
if (err == 0) {
150
err = gpio_direction_output(NET2BIG_GPIO_SATA_POWER_REQ, 0);
151
if (err)
152
gpio_free(NET2BIG_GPIO_SATA_POWER_REQ);
153
}
154
if (err) {
155
pr_err("net2big: failed to setup SATA power request GPIO\n");
156
goto err_free_2;
157
}
158
159
if (gpio_get_value(NET2BIG_GPIO_SATA0_POWER) &&
160
gpio_get_value(NET2BIG_GPIO_SATA1_POWER)) {
161
return;
162
}
163
164
/*
165
* SATA power up on both disk is done by pulling high the CPLD power
166
* request line. The 300ms delay is related to the CPLD clock and is
167
* needed to be sure that the CPLD has take into account the low line
168
* status.
169
*/
170
msleep(300);
171
gpio_set_value(NET2BIG_GPIO_SATA_POWER_REQ, 1);
172
pr_info("net2big: power up SATA hard disks\n");
173
174
return;
175
176
err_free_2:
177
gpio_free(NET2BIG_GPIO_SATA1_POWER);
178
err_free_1:
179
gpio_free(NET2BIG_GPIO_SATA0_POWER);
180
181
return;
182
}
183
184
/*****************************************************************************
185
* GPIO LEDs
186
****************************************************************************/
187
188
/*
189
* The power front LEDs (blue and red) and SATA red LEDs are controlled via a
190
* single GPIO line and are compatible with the leds-gpio driver.
191
*
192
* The SATA blue LEDs have some hardware blink capabilities which are detailed
193
* in the following array:
194
*
195
* SATAx blue LED | SATAx activity | LED state
196
* | |
197
* 0 | 0 | blink (rate 300ms)
198
* 1 | 0 | off
199
* ? | 1 | on
200
*
201
* Notes: The blue and the red front LED's can't be on at the same time.
202
* Blue LED have priority.
203
*/
204
205
#define NET2BIG_GPIO_PWR_RED_LED 6
206
#define NET2BIG_GPIO_PWR_BLUE_LED 16
207
#define NET2BIG_GPIO_PWR_LED_BLINK_STOP 7
208
209
#define NET2BIG_GPIO_SATA0_RED_LED 11
210
#define NET2BIG_GPIO_SATA1_RED_LED 10
211
212
#define NET2BIG_GPIO_SATA0_BLUE_LED 17
213
#define NET2BIG_GPIO_SATA1_BLUE_LED 13
214
215
static struct gpio_led net2big_leds[] = {
216
{
217
.name = "net2big:red:power",
218
},
219
{
220
.name = "net2big:blue:power",
221
},
222
{
223
.name = "net2big:red:sata0",
224
},
225
{
226
.name = "net2big:red:sata1",
227
},
228
};
229
230
static struct gpiod_lookup_table net2big_leds_gpio_table = {
231
.dev_id = "leds-gpio",
232
.table = {
233
GPIO_LOOKUP_IDX("orion_gpio0", NET2BIG_GPIO_PWR_RED_LED, NULL,
234
0, GPIO_ACTIVE_HIGH),
235
GPIO_LOOKUP_IDX("orion_gpio0", NET2BIG_GPIO_PWR_BLUE_LED, NULL,
236
1, GPIO_ACTIVE_HIGH),
237
GPIO_LOOKUP_IDX("orion_gpio0", NET2BIG_GPIO_SATA0_RED_LED, NULL,
238
2, GPIO_ACTIVE_HIGH),
239
GPIO_LOOKUP_IDX("orion_gpio0", NET2BIG_GPIO_SATA1_RED_LED, NULL,
240
3, GPIO_ACTIVE_HIGH),
241
{ },
242
},
243
};
244
245
static struct gpio_led_platform_data net2big_led_data = {
246
.num_leds = ARRAY_SIZE(net2big_leds),
247
.leds = net2big_leds,
248
};
249
250
static struct platform_device net2big_gpio_leds = {
251
.name = "leds-gpio",
252
.id = -1,
253
.dev = {
254
.platform_data = &net2big_led_data,
255
},
256
};
257
258
static void __init net2big_gpio_leds_init(void)
259
{
260
int err;
261
262
/* Stop initial CPLD slow red/blue blinking on power LED. */
263
err = gpio_request(NET2BIG_GPIO_PWR_LED_BLINK_STOP,
264
"Power LED blink stop");
265
if (err == 0) {
266
err = gpio_direction_output(NET2BIG_GPIO_PWR_LED_BLINK_STOP, 1);
267
if (err)
268
gpio_free(NET2BIG_GPIO_PWR_LED_BLINK_STOP);
269
}
270
if (err)
271
pr_err("net2big: failed to setup power LED blink GPIO\n");
272
273
/*
274
* Configure SATA0 and SATA1 blue LEDs to blink in relation with the
275
* hard disk activity.
276
*/
277
err = gpio_request(NET2BIG_GPIO_SATA0_BLUE_LED,
278
"SATA0 blue LED control");
279
if (err == 0) {
280
err = gpio_direction_output(NET2BIG_GPIO_SATA0_BLUE_LED, 1);
281
if (err)
282
gpio_free(NET2BIG_GPIO_SATA0_BLUE_LED);
283
}
284
if (err)
285
pr_err("net2big: failed to setup SATA0 blue LED GPIO\n");
286
287
err = gpio_request(NET2BIG_GPIO_SATA1_BLUE_LED,
288
"SATA1 blue LED control");
289
if (err == 0) {
290
err = gpio_direction_output(NET2BIG_GPIO_SATA1_BLUE_LED, 1);
291
if (err)
292
gpio_free(NET2BIG_GPIO_SATA1_BLUE_LED);
293
}
294
if (err)
295
pr_err("net2big: failed to setup SATA1 blue LED GPIO\n");
296
297
gpiod_add_lookup_table(&net2big_leds_gpio_table);
298
platform_device_register(&net2big_gpio_leds);
299
}
300
301
/****************************************************************************
302
* GPIO keys
303
****************************************************************************/
304
305
#define NET2BIG_GPIO_PUSH_BUTTON 18
306
#define NET2BIG_GPIO_POWER_SWITCH_ON 8
307
#define NET2BIG_GPIO_POWER_SWITCH_OFF 9
308
309
#define NET2BIG_SWITCH_POWER_ON 0x1
310
#define NET2BIG_SWITCH_POWER_OFF 0x2
311
312
static struct gpio_keys_button net2big_buttons[] = {
313
{
314
.type = EV_SW,
315
.code = NET2BIG_SWITCH_POWER_OFF,
316
.gpio = NET2BIG_GPIO_POWER_SWITCH_OFF,
317
.desc = "Power rocker switch (auto|off)",
318
.active_low = 0,
319
},
320
{
321
.type = EV_SW,
322
.code = NET2BIG_SWITCH_POWER_ON,
323
.gpio = NET2BIG_GPIO_POWER_SWITCH_ON,
324
.desc = "Power rocker switch (on|auto)",
325
.active_low = 0,
326
},
327
{
328
.type = EV_KEY,
329
.code = KEY_POWER,
330
.gpio = NET2BIG_GPIO_PUSH_BUTTON,
331
.desc = "Front Push Button",
332
.active_low = 0,
333
},
334
};
335
336
static struct gpio_keys_platform_data net2big_button_data = {
337
.buttons = net2big_buttons,
338
.nbuttons = ARRAY_SIZE(net2big_buttons),
339
};
340
341
static struct platform_device net2big_gpio_buttons = {
342
.name = "gpio-keys",
343
.id = -1,
344
.dev = {
345
.platform_data = &net2big_button_data,
346
},
347
};
348
349
/*****************************************************************************
350
* General Setup
351
****************************************************************************/
352
353
static unsigned int net2big_mpp_modes[] __initdata = {
354
MPP0_GPIO, /* Raid mode (bit 0) */
355
MPP1_GPIO, /* USB port 2 fuse (0 = Fail, 1 = Ok) */
356
MPP2_GPIO, /* Raid mode (bit 1) */
357
MPP3_GPIO, /* Board ID (bit 0) */
358
MPP4_GPIO, /* Fan activity (0 = Off, 1 = On) */
359
MPP5_GPIO, /* Fan fail detection */
360
MPP6_GPIO, /* Red front LED (0 = Off, 1 = On) */
361
MPP7_GPIO, /* Disable initial blinking on front LED */
362
MPP8_GPIO, /* Rear power switch (on|auto) */
363
MPP9_GPIO, /* Rear power switch (auto|off) */
364
MPP10_GPIO, /* SATA 1 red LED (0 = Off, 1 = On) */
365
MPP11_GPIO, /* SATA 0 red LED (0 = Off, 1 = On) */
366
MPP12_GPIO, /* Board ID (bit 1) */
367
MPP13_GPIO, /* SATA 1 blue LED blink control */
368
MPP14_SATA_LED,
369
MPP15_SATA_LED,
370
MPP16_GPIO, /* Blue front LED control */
371
MPP17_GPIO, /* SATA 0 blue LED blink control */
372
MPP18_GPIO, /* Front button (0 = Released, 1 = Pushed ) */
373
MPP19_GPIO, /* SATA{0,1} power On/Off request */
374
0,
375
/* 22: USB port 1 fuse (0 = Fail, 1 = Ok) */
376
/* 23: SATA 0 power status */
377
/* 24: Board power off */
378
/* 25: SATA 1 power status */
379
};
380
381
#define NET2BIG_GPIO_POWER_OFF 24
382
383
static void net2big_power_off(void)
384
{
385
gpio_set_value(NET2BIG_GPIO_POWER_OFF, 1);
386
}
387
388
static void __init net2big_init(void)
389
{
390
/*
391
* Setup basic Orion functions. Need to be called early.
392
*/
393
orion5x_init();
394
395
orion5x_mpp_conf(net2big_mpp_modes);
396
397
/*
398
* Configure peripherals.
399
*/
400
orion5x_ehci0_init();
401
orion5x_ehci1_init();
402
orion5x_eth_init(&net2big_eth_data);
403
orion5x_i2c_init();
404
orion5x_uart0_init();
405
orion5x_xor_init();
406
407
net2big_sata_power_init();
408
orion5x_sata_init(&net2big_sata_data);
409
410
mvebu_mbus_add_window_by_id(ORION_MBUS_DEVBUS_BOOT_TARGET,
411
ORION_MBUS_DEVBUS_BOOT_ATTR,
412
NET2BIG_NOR_BOOT_BASE,
413
NET2BIG_NOR_BOOT_SIZE);
414
platform_device_register(&net2big_nor_flash);
415
416
platform_device_register(&net2big_gpio_buttons);
417
net2big_gpio_leds_init();
418
419
i2c_register_board_info(0, net2big_i2c_devices,
420
ARRAY_SIZE(net2big_i2c_devices));
421
422
orion_gpio_set_valid(NET2BIG_GPIO_POWER_OFF, 1);
423
424
if (gpio_request(NET2BIG_GPIO_POWER_OFF, "power-off") == 0 &&
425
gpio_direction_output(NET2BIG_GPIO_POWER_OFF, 0) == 0)
426
register_platform_power_off(net2big_power_off);
427
else
428
pr_err("net2big: failed to configure power-off GPIO\n");
429
430
pr_notice("net2big: Flash writing is not yet supported.\n");
431
}
432
433
/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
434
MACHINE_START(NET2BIG, "LaCie 2Big Network")
435
.atag_offset = 0x100,
436
.nr_irqs = ORION5X_NR_IRQS,
437
.init_machine = net2big_init,
438
.map_io = orion5x_map_io,
439
.init_early = orion5x_init_early,
440
.init_irq = orion5x_init_irq,
441
.init_time = orion5x_timer_init,
442
.fixup = tag_fixup_mem32,
443
.restart = orion5x_restart,
444
MACHINE_END
445
446