@@ -113,7 +113,51 @@ static struct gpiod_lookup_table asustor_fs6700_gpio_leds_lookup = {
113
113
},
114
114
};
115
115
116
- static struct gpiod_lookup_table asustor_6700_gpio_leds_lookup = {
116
+ static struct gpiod_lookup_table asustor_as6702_gpio_leds_lookup = {
117
+ .dev_id = "leds-gpio" ,
118
+ .table = {
119
+ // 0: AS6702T and AS5402T don't have a front panel to illuminate
120
+ // 1: they don't have a LCD either
121
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 56 , NULL , 2 , GPIO_ACTIVE_LOW ), // blue:power
122
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 8 , NULL , 3 , GPIO_ACTIVE_LOW ), // red:power
123
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 31 , NULL , 4 , GPIO_ACTIVE_LOW ), // green:status
124
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 49 , NULL , 5 , GPIO_ACTIVE_LOW ), // red:status
125
+ // 6
126
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 21 , NULL , 7 , GPIO_ACTIVE_LOW ), // green:usb
127
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 55 , NULL , 8 , GPIO_ACTIVE_HIGH ), // blue:lan
128
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 12 , NULL , 9 , GPIO_ACTIVE_HIGH ), // sata1:green:disk
129
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 13 , NULL , 10 , GPIO_ACTIVE_LOW ), // sata1:red:disk
130
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 46 , NULL , 11 , GPIO_ACTIVE_HIGH ), // sata2:green:disk
131
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 47 , NULL , 12 , GPIO_ACTIVE_LOW ), // sata2:red:disk
132
+ {}
133
+ },
134
+ };
135
+
136
+ static struct gpiod_lookup_table asustor_as6704_gpio_leds_lookup = {
137
+ .dev_id = "leds-gpio" ,
138
+ .table = {
139
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 29 , NULL , 0 , GPIO_ACTIVE_HIGH ), // power:front_panel
140
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 59 , NULL , 1 , GPIO_ACTIVE_HIGH ), // power:lcd
141
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 56 , NULL , 2 , GPIO_ACTIVE_LOW ), // blue:power
142
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 8 , NULL , 3 , GPIO_ACTIVE_LOW ), // red:power
143
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 31 , NULL , 4 , GPIO_ACTIVE_LOW ), // green:status
144
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 49 , NULL , 5 , GPIO_ACTIVE_LOW ), // red:status
145
+ // 6
146
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 21 , NULL , 7 , GPIO_ACTIVE_LOW ), // green:usb
147
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 55 , NULL , 8 , GPIO_ACTIVE_HIGH ), // blue:lan
148
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 12 , NULL , 9 , GPIO_ACTIVE_HIGH ), // sata1:green:disk
149
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 13 , NULL , 10 , GPIO_ACTIVE_LOW ), // sata1:red:disk
150
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 46 , NULL , 11 , GPIO_ACTIVE_HIGH ), // sata2:green:disk
151
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 47 , NULL , 12 , GPIO_ACTIVE_LOW ), // sata2:red:disk
152
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 51 , NULL , 13 , GPIO_ACTIVE_HIGH ), // sata3:green:disk
153
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 52 , NULL , 14 , GPIO_ACTIVE_LOW ), // sata3:red:disk
154
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 63 , NULL , 15 , GPIO_ACTIVE_HIGH ), // sata4:green:disk
155
+ GPIO_LOOKUP_IDX (GPIO_IT87 , 48 , NULL , 16 , GPIO_ACTIVE_LOW ), // sata4:red:disk
156
+ {}
157
+ },
158
+ };
159
+
160
+ static struct gpiod_lookup_table asustor_as6706_gpio_leds_lookup = {
117
161
.dev_id = "leds-gpio" ,
118
162
.table = {
119
163
GPIO_LOOKUP_IDX (GPIO_IT87 , 29 , NULL , 0 , GPIO_ACTIVE_HIGH ), // power:front_panel
@@ -263,44 +307,111 @@ struct asustor_driver_data {
263
307
struct gpiod_lookup_table * keys ;
264
308
};
265
309
266
- #define VALID_OVERRIDE_NAMES "AS6xx, AS61xx, AS66xx, AS67xx, FS67xx"
310
+ #define VALID_OVERRIDE_NAMES \
311
+ "AS6xx, AS61xx, AS66xx, AS6702, AS6704, AS6706, FS6706, FS6712"
267
312
268
313
// NOTE: if you add another device here, update VALID_OVERRIDE_NAMES accordingly!
269
314
270
- static struct asustor_driver_data asustor_fs6700_driver_data = {
271
- .name = "FS67xx" ,
272
- // FS67xx needs to match PCI devices because it has the same DMI data as *A*S67xx
315
+ /*
316
+ * Unfortunately, AS67xx and FS67xx can't be told apart by DMI, they all identify as
317
+ * "Intel Corporation" - "Jasper Lake Client Platform", so we need to match PCI devices.
318
+ *
319
+ * How to tell AS67xx and FS6xx apart:
320
+ *
321
+ * only AS6702T/AS5402T has [8086:4dd3] Intel Corporation Jasper Lake SATA AHCI Controller
322
+ * (only [AF]S67xx: [8086:4dc8] Intel Corporation Jasper Lake HD Audio
323
+ * - but for now I think AS670xT vs AS540xT doesn't matter. Not sure if AS5404T has this; AS5402T doesn't)
324
+ *
325
+ * only AS6704T has [1b21:1164] ASMedia Technology Inc. ASM1164 Serial ATA AHCI Controller
326
+ * - TODO: does AS5404T also use this? until disproven, I assume it does
327
+ * only AS6706T has [1b21:1166] ASMedia Technology Inc. ASM1166 Serial ATA Controller
328
+ *
329
+ * only FS6712X has [1b21:2806] ASMedia Technology Inc. ASM2806 4-Port PCIe x2 Gen3 Packet Switch
330
+ * (it doesn't have any SATA controller)
331
+ * FS6706T does not have any SATA controller and no ASMedia PCIe packet switch either
332
+ */
333
+
334
+ static struct asustor_driver_data asustor_as6702_driver_data = {
335
+ .name = "AS6702" ,
336
+ .pci_matches = {
337
+ // SATA controller [0106]: Intel Corporation Jasper Lake SATA AHCI Controller [8086:4dd3] (rev 01)
338
+ // Both AS6702T and AS5402T use this SATA controller (the other devices don't)
339
+ { 0x8086 , 0x4dd3 , 1 , 1 }
340
+ },
341
+ .leds = & asustor_as6702_gpio_leds_lookup ,
342
+ .keys = & asustor_6100_gpio_keys_lookup ,
343
+ };
344
+
345
+ static struct asustor_driver_data asustor_as6704_driver_data = {
346
+ .name = "AS6704" ,
347
+ .pci_matches = {
348
+ // SATA controller: ASMedia Technology Inc. ASM1164 Serial ATA AHCI Controller [1b21:1164] (rev 02)
349
+ // This SATA controller is used by AS6704T, and hopefully by AS5404T as well, but
350
+ // not by any of the other AS67xx or FS67xx devices
351
+ { 0x1b21 , 0x1164 , 1 , 1 }
352
+ },
353
+ .leds = & asustor_as6704_gpio_leds_lookup ,
354
+ .keys = & asustor_6100_gpio_keys_lookup ,
355
+ };
356
+
357
+ static struct asustor_driver_data asustor_as6706_driver_data = {
358
+ .name = "AS6706" ,
359
+ .pci_matches = {
360
+ // SATA controller [0106]: ASMedia Technology Inc. ASM1166 Serial ATA Controller [1b21:1166] (rev 02)
361
+ // only used by AS6706T; there (currently?) is no AS5406T
362
+ { 0x1b21 , 0x1166 , 1 , 1 }
363
+ // (BTW, AS6706T also has 5x "ASM2812 6-Port PCIe x4 Gen3 Packet Switch" [1b21:2812],
364
+ // which thankfully is NOT the same one that FS6712 uses. Also it allows replacing the
365
+ // m.2 NVME slots with a 10Gbit NIC, could be that then the packet switch goes away, IDK)
366
+ },
367
+ .leds = & asustor_as6706_gpio_leds_lookup ,
368
+ .keys = & asustor_6100_gpio_keys_lookup ,
369
+ };
370
+
371
+ static struct asustor_driver_data asustor_fs6712_driver_data = {
372
+ .name = "FS6712" ,
273
373
.pci_matches = {
274
374
// PCI bridge: ASMedia Technology Inc. ASM2806 4-Port PCIe x2 Gen3 Packet Switch (rev 01)
275
- // FS6712X seems to have 15 of these, no idea about FS6706T (so I keep min_count at 1)
276
- // currently the upper limit doesn't matter so I just use DEVICE_COUNT_MAX
375
+ // apparently only FS6712X uses this - 15 of those turn up in lspci, at least if
376
+ // all m.2 NVME slots have a SSD installed. I guess it's safest to match that at least
377
+ // one of these exist; upper limit doesn't matter, so just use DEVICE_COUNT_MAX
277
378
{ 0x1b21 , 0x2806 , 1 , DEVICE_COUNT_MAX },
278
379
},
279
380
.leds = & asustor_fs6700_gpio_leds_lookup ,
280
381
.keys = & asustor_fs6700_gpio_keys_lookup ,
281
382
};
282
383
283
- static struct asustor_driver_data asustor_6700_driver_data = {
284
- .name = "AS67xx" ,
285
- // AS67xx needs to match PCI devices because it has the same DMI data as *F*S67xx
384
+ static struct asustor_driver_data asustor_fs6706_driver_data = {
385
+ .name = "FS6706" ,
286
386
.pci_matches = {
287
- // PCI bridge: ASMedia Technology Inc. ASM2806 4-Port PCIe x2 Gen3 Packet Switch (rev 01)
288
- // *F*S67xx seems to use these, *A*S67xx doesn't, so expect 0
289
- // (BTW, AS6706T has 5x "ASM2812 6-Port PCIe x4 Gen3 Packet Switch" [1b21:2812], I hope *F*S6706T doesn't)
387
+ // FS6706T doesn't have that ASMedia PCI bridge / PCIe Packet switch
290
388
{ 0x1b21 , 0x2806 , 0 , 0 },
389
+ // .. it doesn't have any of the SATA controllers either
390
+ { 0x8086 , 0x4dd3 , 0 , 0 }, // .. not the Intel one used by AS6702T/AS5402T
391
+ { 0x1b21 , 0x1164 , 0 , 0 }, // .. neither the ASMedia one used by AS6704T
392
+ { 0x1b21 , 0x1166 , 0 , 0 }, // .. nor the ASMedia one used by AS6706T
291
393
},
292
- .leds = & asustor_6700_gpio_leds_lookup ,
293
- .keys = & asustor_6100_gpio_keys_lookup ,
394
+ .leds = & asustor_fs6700_gpio_leds_lookup ,
395
+ .keys = & asustor_fs6700_gpio_keys_lookup ,
294
396
};
295
397
398
+ /*
399
+ * It currently looks like the older systems are easier to tell apart, at least if one doesn't insist
400
+ * on detecting the 2 vs 4 vs 6 drives versions (I only did this for AS67xx because I had to do the
401
+ * advanced detection anyway)
402
+ */
403
+
296
404
static struct asustor_driver_data asustor_6600_driver_data = {
297
405
// NOTE: This is (currently?) the same as for AS6700
298
406
// because it seems to use the same GPIO numbers,
299
407
// but listed extra for the different name
300
408
.name = "AS66xx" ,
301
409
// This (and the remaining systems) don't need to match PCI devices to be detected,
302
410
// so they're not set here (and thus initialized to all-zero)
303
- .leds = & asustor_6700_gpio_leds_lookup ,
411
+
412
+ // the LED GPIOs are the same as in AS67xx, so use the one from AS6704 which should work for
413
+ // both AS6602T and AS6604T (an AS66xx with more than 4 drives doesn't seem to exist)
414
+ .leds = & asustor_as6704_gpio_leds_lookup ,
304
415
.keys = & asustor_6100_gpio_keys_lookup ,
305
416
};
306
417
@@ -316,34 +427,61 @@ static struct asustor_driver_data asustor_600_driver_data = {
316
427
.keys = & asustor_600_gpio_keys_lookup ,
317
428
};
318
429
319
- // NOTE: Don't use this table with dmi_first_match(), because it has two entries that
320
- // match the same (AS67xx and FS67xx). find_matching_asustor_system() handles
430
+ // NOTE: Don't use this table with dmi_first_match(), because it has several entries that
431
+ // match the same (for AS67xx and FS67xx). find_matching_asustor_system() handles
321
432
// that by also matching PCI devices from asustor_driver_data::pci_matches.
322
433
// This table only exists in this form (instead of just using an array of
323
434
// asustor_driver_data) for MODULE_DEVICE_TABLE().
324
435
static const struct dmi_system_id asustor_systems [] = {
325
436
// NOTE: each entry in this table must have its own unique asustor_driver_data
326
437
// (having a unique .name) set as .driver_data
438
+
439
+ // The following devices all use the same DMI matches and are actually told apart by
440
+ // our custom matching logic in find_matching_asustor_system() also takes
441
+ // driver_data->pci_matches[] into account.
442
+ // See also the bigger comment above about AS67xx vs FS67xx
443
+ {
444
+ // NOTE: This not only matches (and works with) AS6702T (Lockerstor Gen2),
445
+ // but also AS5402T (Nimbustor Gen2)
446
+ .matches = {
447
+ DMI_EXACT_MATCH (DMI_SYS_VENDOR , "Intel Corporation" ),
448
+ DMI_EXACT_MATCH (DMI_PRODUCT_NAME , "Jasper Lake Client Platform" ),
449
+ },
450
+ .driver_data = & asustor_as6702_driver_data ,
451
+ },
452
+ {
453
+ // NOTE: This not only matches (and works with) AS6704T (Lockerstor Gen2),
454
+ // but (hopefully!) also AS5404T (Nimbustor Gen2)
455
+ .matches = {
456
+ DMI_EXACT_MATCH (DMI_SYS_VENDOR , "Intel Corporation" ),
457
+ DMI_EXACT_MATCH (DMI_PRODUCT_NAME , "Jasper Lake Client Platform" ),
458
+ },
459
+ .driver_data = & asustor_as6704_driver_data ,
460
+ },
327
461
{
328
- // NOTE: yes, this is the same DMI match as the next entry, because just by DMI,
329
- // FS67xx and AS67xx can't be told apart. But our custom matching logic
330
- // in find_matching_asustor_system() also takes driver_data->pci_matches[]
331
- // into account, so that should be ok.
332
462
.matches = {
333
463
DMI_EXACT_MATCH (DMI_SYS_VENDOR , "Intel Corporation" ),
334
464
DMI_EXACT_MATCH (DMI_PRODUCT_NAME , "Jasper Lake Client Platform" ),
335
465
},
336
- .driver_data = & asustor_fs6700_driver_data ,
466
+ .driver_data = & asustor_as6706_driver_data ,
337
467
},
468
+ // *F*S67xx:
338
469
{
339
- // NOTE: This not only matches (and works with) AS670xT (Lockerstor Gen2),
340
- // but also AS540xT (Nimbustor Gen2)
341
470
.matches = {
342
471
DMI_EXACT_MATCH (DMI_SYS_VENDOR , "Intel Corporation" ),
343
472
DMI_EXACT_MATCH (DMI_PRODUCT_NAME , "Jasper Lake Client Platform" ),
344
473
},
345
- .driver_data = & asustor_6700_driver_data ,
474
+ .driver_data = & asustor_fs6706_driver_data ,
346
475
},
476
+ {
477
+ .matches = {
478
+ DMI_EXACT_MATCH (DMI_SYS_VENDOR , "Intel Corporation" ),
479
+ DMI_EXACT_MATCH (DMI_PRODUCT_NAME , "Jasper Lake Client Platform" ),
480
+ },
481
+ .driver_data = & asustor_fs6712_driver_data ,
482
+ },
483
+
484
+ // older devices can be matched only by DMI
347
485
{
348
486
.matches = {
349
487
DMI_EXACT_MATCH (DMI_SYS_VENDOR , "Insyde" ),
0 commit comments