git: 3023bb49e115 - main - asmc: introduce the concept of generic models

From: Enji Cooper <ngie_at_FreeBSD.org>
Date: Wed, 25 Feb 2026 06:42:28 UTC
The branch main has been updated by ngie:

URL: https://cgit.FreeBSD.org/src/commit/?id=3023bb49e115b4149f9fc0683dabde172ecb1336

commit 3023bb49e115b4149f9fc0683dabde172ecb1336
Author:     Enji Cooper <ngie@FreeBSD.org>
AuthorDate: 2026-02-20 06:37:05 +0000
Commit:     Enji Cooper <ngie@FreeBSD.org>
CommitDate: 2026-02-25 06:41:42 +0000

    asmc: introduce the concept of generic models
    
    Having to enter in each of the models for Apple hardware, recompiling,
    etc, is tedious. Provide generic models so end-users can leverage some
    of the capabilities provided by the driver, i.e., common features like
    minimal fans and lights (if present on the generic model) support.
    
    The generic models are as follows:
    - Macmini
    - MacBookAir
    - MacBookPro
    - MacPro
    
    This sort of follows the pattern established by the `applesmc` driver in
    Linux.
    
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D55395
---
 sys/dev/asmc/asmc.c | 80 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 67 insertions(+), 13 deletions(-)

diff --git a/sys/dev/asmc/asmc.c b/sys/dev/asmc/asmc.c
index 35c050cab100..cf977071cc69 100644
--- a/sys/dev/asmc/asmc.c
+++ b/sys/dev/asmc/asmc.c
@@ -176,6 +176,11 @@ static const struct asmc_model *asmc_match(device_t dev);
 			 .smc_light_right = NULL, \
 			 .smc_light_control = NULL
 
+#define	ASMC_TEMPS_FUNCS_DISABLED \
+			  .smc_temps = {},		\
+			  .smc_tempnames = {},		\
+			  .smc_tempdescs = {}		\
+
 static const struct asmc_model asmc_models[] = {
 	{
 	  "MacBook1,1", "Apple SMC MacBook Core Duo",
@@ -517,8 +522,42 @@ static const struct asmc_model asmc_models[] = {
 	  ASMC_FAN_FUNCS2,
 	  ASMC_LIGHT_FUNCS,
 	  ASMC_MBA7_TEMPS, ASMC_MBA7_TEMPNAMES, ASMC_MBA7_TEMPDESCS
+	}
+};
+
+static const struct asmc_model asmc_generic_models[] = {
+	{
+	  .smc_model = "MacBookAir",
+	  .smc_desc = NULL,
+	  ASMC_SMS_FUNCS_DISABLED,
+	  ASMC_FAN_FUNCS2,
+	  ASMC_LIGHT_FUNCS,
+	  ASMC_TEMPS_FUNCS_DISABLED
+	},
+	{
+	  .smc_model = "MacBookPro",
+	  .smc_desc = NULL,
+	  ASMC_SMS_FUNCS_DISABLED,
+	  ASMC_FAN_FUNCS2,
+	  ASMC_LIGHT_FUNCS,
+	  ASMC_TEMPS_FUNCS_DISABLED
+	},
+	{
+	  .smc_model = "MacPro",
+	  .smc_desc = NULL,
+	  ASMC_SMS_FUNCS_DISABLED,
+	  ASMC_FAN_FUNCS2,
+	  ASMC_LIGHT_FUNCS_DISABLED,
+	  ASMC_TEMPS_FUNCS_DISABLED
 	},
-	{ NULL, NULL }
+	{
+	  .smc_model = "Macmini",
+	  .smc_desc = NULL,
+	  ASMC_SMS_FUNCS_DISABLED,
+	  ASMC_FAN_FUNCS2,
+	  ASMC_LIGHT_FUNCS_DISABLED,
+	  ASMC_TEMPS_FUNCS_DISABLED
+	}
 };
 
 #undef ASMC_SMS_FUNCS
@@ -566,28 +605,41 @@ MODULE_DEPEND(asmc, acpi, 1, 1, 1);
 static const struct asmc_model *
 asmc_match(device_t dev)
 {
+	const struct asmc_model *model;
+	char *model_name;
 	int i;
-	char *model;
 
-	model = kern_getenv("smbios.system.product");
-	if (model == NULL)
-		return (NULL);
+	model = NULL;
+
+	model_name = kern_getenv("smbios.system.product");
+	if (model_name == NULL)
+		goto out;
 
-	for (i = 0; asmc_models[i].smc_model; i++) {
-		if (!strncmp(model, asmc_models[i].smc_model, strlen(model))) {
-			freeenv(model);
-			return (&asmc_models[i]);
+	for (i = 0; i < nitems(asmc_models); i++) {
+		if (strncmp(model_name, asmc_models[i].smc_model,
+		    strlen(model_name)) == 0) {
+			model = &asmc_models[i];
+			goto out;
+		}
+	}
+	for (i = 0; i < nitems(asmc_generic_models); i++) {
+		if (strncmp(model_name, asmc_generic_models[i].smc_model,
+		    strlen(asmc_generic_models[i].smc_model)) == 0) {
+			model = &asmc_generic_models[i];
+			goto out;
 		}
 	}
-	freeenv(model);
 
-	return (NULL);
+out:
+	freeenv(model_name);
+	return (model);
 }
 
 static int
 asmc_probe(device_t dev)
 {
 	const struct asmc_model *model;
+	const char *device_desc;
 	int rv;
 
 	if (resource_disabled("asmc", 0))
@@ -597,11 +649,13 @@ asmc_probe(device_t dev)
 		return (rv);
 
 	model = asmc_match(dev);
-	if (!model) {
+	if (model == NULL) {
 		device_printf(dev, "model not recognized\n");
 		return (ENXIO);
 	}
-	device_set_desc(dev, model->smc_desc);
+	device_desc = model->smc_desc == NULL ?
+	    model->smc_model : model->smc_desc;
+	device_set_desc(dev, device_desc);
 
 	return (rv);
 }