162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci/*
462306a36Sopenharmony_ci    card-als100.c - driver for Avance Logic ALS100 based soundcards.
562306a36Sopenharmony_ci    Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it>
662306a36Sopenharmony_ci    Copyright (C) 1999-2002 by Massimo Piccioni <dafastidio@libero.it>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci    Thanks to Pierfrancesco 'qM2' Passerini.
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci    Generalised for soundcards based on DT-0196 and ALS-007 chips
1162306a36Sopenharmony_ci    by Jonathan Woithe <jwoithe@just42.net>: June 2002.
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci*/
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/init.h>
1662306a36Sopenharmony_ci#include <linux/wait.h>
1762306a36Sopenharmony_ci#include <linux/time.h>
1862306a36Sopenharmony_ci#include <linux/pnp.h>
1962306a36Sopenharmony_ci#include <linux/module.h>
2062306a36Sopenharmony_ci#include <sound/core.h>
2162306a36Sopenharmony_ci#include <sound/initval.h>
2262306a36Sopenharmony_ci#include <sound/mpu401.h>
2362306a36Sopenharmony_ci#include <sound/opl3.h>
2462306a36Sopenharmony_ci#include <sound/sb.h>
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define PFX "als100: "
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ciMODULE_DESCRIPTION("Avance Logic ALS007/ALS1X0");
2962306a36Sopenharmony_ciMODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
3062306a36Sopenharmony_ciMODULE_LICENSE("GPL");
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_cistatic int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
3362306a36Sopenharmony_cistatic char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
3462306a36Sopenharmony_cistatic bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;	/* Enable this card */
3562306a36Sopenharmony_cistatic long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* PnP setup */
3662306a36Sopenharmony_cistatic long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* PnP setup */
3762306a36Sopenharmony_cistatic long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;	/* PnP setup */
3862306a36Sopenharmony_cistatic int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;	/* PnP setup */
3962306a36Sopenharmony_cistatic int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;	/* PnP setup */
4062306a36Sopenharmony_cistatic int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;	/* PnP setup */
4162306a36Sopenharmony_cistatic int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;	/* PnP setup */
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cimodule_param_array(index, int, NULL, 0444);
4462306a36Sopenharmony_ciMODULE_PARM_DESC(index, "Index value for Avance Logic based soundcard.");
4562306a36Sopenharmony_cimodule_param_array(id, charp, NULL, 0444);
4662306a36Sopenharmony_ciMODULE_PARM_DESC(id, "ID string for Avance Logic based soundcard.");
4762306a36Sopenharmony_cimodule_param_array(enable, bool, NULL, 0444);
4862306a36Sopenharmony_ciMODULE_PARM_DESC(enable, "Enable Avance Logic based soundcard.");
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ciMODULE_ALIAS("snd-dt019x");
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_cistruct snd_card_als100 {
5362306a36Sopenharmony_ci	struct pnp_dev *dev;
5462306a36Sopenharmony_ci	struct pnp_dev *devmpu;
5562306a36Sopenharmony_ci	struct pnp_dev *devopl;
5662306a36Sopenharmony_ci	struct snd_sb *chip;
5762306a36Sopenharmony_ci};
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cistatic const struct pnp_card_device_id snd_als100_pnpids[] = {
6062306a36Sopenharmony_ci	/* DT197A30 */
6162306a36Sopenharmony_ci	{ .id = "RWB1688",
6262306a36Sopenharmony_ci	  .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
6362306a36Sopenharmony_ci	  .driver_data = SB_HW_DT019X },
6462306a36Sopenharmony_ci	/* DT0196 / ALS-007 */
6562306a36Sopenharmony_ci	{ .id = "ALS0007",
6662306a36Sopenharmony_ci	  .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
6762306a36Sopenharmony_ci	  .driver_data = SB_HW_DT019X },
6862306a36Sopenharmony_ci	/* ALS100 - PRO16PNP */
6962306a36Sopenharmony_ci	{ .id = "ALS0001",
7062306a36Sopenharmony_ci	  .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
7162306a36Sopenharmony_ci	  .driver_data = SB_HW_ALS100 },
7262306a36Sopenharmony_ci	/* ALS110 - MF1000 - Digimate 3D Sound */
7362306a36Sopenharmony_ci	{ .id = "ALS0110",
7462306a36Sopenharmony_ci	  .devs = { { "@@@1001" }, { "@X@1001" }, { "@H@1001" } },
7562306a36Sopenharmony_ci	  .driver_data = SB_HW_ALS100 },
7662306a36Sopenharmony_ci	/* ALS120 */
7762306a36Sopenharmony_ci	{ .id = "ALS0120",
7862306a36Sopenharmony_ci	  .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } },
7962306a36Sopenharmony_ci	  .driver_data = SB_HW_ALS100 },
8062306a36Sopenharmony_ci	/* ALS200 */
8162306a36Sopenharmony_ci	{ .id = "ALS0200",
8262306a36Sopenharmony_ci	  .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0001" } },
8362306a36Sopenharmony_ci	  .driver_data = SB_HW_ALS100 },
8462306a36Sopenharmony_ci	/* ALS200 OEM */
8562306a36Sopenharmony_ci	{ .id = "ALS0200",
8662306a36Sopenharmony_ci	  .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0020" } },
8762306a36Sopenharmony_ci	  .driver_data = SB_HW_ALS100 },
8862306a36Sopenharmony_ci	/* RTL3000 */
8962306a36Sopenharmony_ci	{ .id = "RTL3000",
9062306a36Sopenharmony_ci	  .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } },
9162306a36Sopenharmony_ci	  .driver_data = SB_HW_ALS100 },
9262306a36Sopenharmony_ci	{ .id = "" } /* end */
9362306a36Sopenharmony_ci};
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(pnp_card, snd_als100_pnpids);
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_cistatic int snd_card_als100_pnp(int dev, struct snd_card_als100 *acard,
9862306a36Sopenharmony_ci			       struct pnp_card_link *card,
9962306a36Sopenharmony_ci			       const struct pnp_card_device_id *id)
10062306a36Sopenharmony_ci{
10162306a36Sopenharmony_ci	struct pnp_dev *pdev;
10262306a36Sopenharmony_ci	int err;
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
10562306a36Sopenharmony_ci	if (acard->dev == NULL)
10662306a36Sopenharmony_ci		return -ENODEV;
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci	acard->devmpu = pnp_request_card_device(card, id->devs[1].id, acard->dev);
10962306a36Sopenharmony_ci	acard->devopl = pnp_request_card_device(card, id->devs[2].id, acard->dev);
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	pdev = acard->dev;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	err = pnp_activate_dev(pdev);
11462306a36Sopenharmony_ci	if (err < 0) {
11562306a36Sopenharmony_ci		snd_printk(KERN_ERR PFX "AUDIO pnp configure failure\n");
11662306a36Sopenharmony_ci		return err;
11762306a36Sopenharmony_ci	}
11862306a36Sopenharmony_ci	port[dev] = pnp_port_start(pdev, 0);
11962306a36Sopenharmony_ci	if (id->driver_data == SB_HW_DT019X)
12062306a36Sopenharmony_ci		dma8[dev] = pnp_dma(pdev, 0);
12162306a36Sopenharmony_ci	else {
12262306a36Sopenharmony_ci		dma8[dev] = pnp_dma(pdev, 1);
12362306a36Sopenharmony_ci		dma16[dev] = pnp_dma(pdev, 0);
12462306a36Sopenharmony_ci	}
12562306a36Sopenharmony_ci	irq[dev] = pnp_irq(pdev, 0);
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci	pdev = acard->devmpu;
12862306a36Sopenharmony_ci	if (pdev != NULL) {
12962306a36Sopenharmony_ci		err = pnp_activate_dev(pdev);
13062306a36Sopenharmony_ci		if (err < 0)
13162306a36Sopenharmony_ci			goto __mpu_error;
13262306a36Sopenharmony_ci		mpu_port[dev] = pnp_port_start(pdev, 0);
13362306a36Sopenharmony_ci		mpu_irq[dev] = pnp_irq(pdev, 0);
13462306a36Sopenharmony_ci	} else {
13562306a36Sopenharmony_ci	     __mpu_error:
13662306a36Sopenharmony_ci	     	if (pdev) {
13762306a36Sopenharmony_ci		     	pnp_release_card_device(pdev);
13862306a36Sopenharmony_ci	     		snd_printk(KERN_ERR PFX "MPU401 pnp configure failure, skipping\n");
13962306a36Sopenharmony_ci	     	}
14062306a36Sopenharmony_ci	     	acard->devmpu = NULL;
14162306a36Sopenharmony_ci	     	mpu_port[dev] = -1;
14262306a36Sopenharmony_ci	}
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	pdev = acard->devopl;
14562306a36Sopenharmony_ci	if (pdev != NULL) {
14662306a36Sopenharmony_ci		err = pnp_activate_dev(pdev);
14762306a36Sopenharmony_ci		if (err < 0)
14862306a36Sopenharmony_ci			goto __fm_error;
14962306a36Sopenharmony_ci		fm_port[dev] = pnp_port_start(pdev, 0);
15062306a36Sopenharmony_ci	} else {
15162306a36Sopenharmony_ci	      __fm_error:
15262306a36Sopenharmony_ci	     	if (pdev) {
15362306a36Sopenharmony_ci		     	pnp_release_card_device(pdev);
15462306a36Sopenharmony_ci	     		snd_printk(KERN_ERR PFX "OPL3 pnp configure failure, skipping\n");
15562306a36Sopenharmony_ci	     	}
15662306a36Sopenharmony_ci	     	acard->devopl = NULL;
15762306a36Sopenharmony_ci	     	fm_port[dev] = -1;
15862306a36Sopenharmony_ci	}
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci	return 0;
16162306a36Sopenharmony_ci}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_cistatic int snd_card_als100_probe(int dev,
16462306a36Sopenharmony_ci				 struct pnp_card_link *pcard,
16562306a36Sopenharmony_ci				 const struct pnp_card_device_id *pid)
16662306a36Sopenharmony_ci{
16762306a36Sopenharmony_ci	int error;
16862306a36Sopenharmony_ci	struct snd_sb *chip;
16962306a36Sopenharmony_ci	struct snd_card *card;
17062306a36Sopenharmony_ci	struct snd_card_als100 *acard;
17162306a36Sopenharmony_ci	struct snd_opl3 *opl3;
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	error = snd_devm_card_new(&pcard->card->dev,
17462306a36Sopenharmony_ci				  index[dev], id[dev], THIS_MODULE,
17562306a36Sopenharmony_ci				  sizeof(struct snd_card_als100), &card);
17662306a36Sopenharmony_ci	if (error < 0)
17762306a36Sopenharmony_ci		return error;
17862306a36Sopenharmony_ci	acard = card->private_data;
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci	error = snd_card_als100_pnp(dev, acard, pcard, pid);
18162306a36Sopenharmony_ci	if (error)
18262306a36Sopenharmony_ci		return error;
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci	if (pid->driver_data == SB_HW_DT019X)
18562306a36Sopenharmony_ci		dma16[dev] = -1;
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ci	error = snd_sbdsp_create(card, port[dev], irq[dev],
18862306a36Sopenharmony_ci				  snd_sb16dsp_interrupt,
18962306a36Sopenharmony_ci				  dma8[dev], dma16[dev],
19062306a36Sopenharmony_ci				  pid->driver_data,
19162306a36Sopenharmony_ci				  &chip);
19262306a36Sopenharmony_ci	if (error < 0)
19362306a36Sopenharmony_ci		return error;
19462306a36Sopenharmony_ci	acard->chip = chip;
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci	if (pid->driver_data == SB_HW_DT019X) {
19762306a36Sopenharmony_ci		strcpy(card->driver, "DT-019X");
19862306a36Sopenharmony_ci		strcpy(card->shortname, "Diamond Tech. DT-019X");
19962306a36Sopenharmony_ci		snprintf(card->longname, sizeof(card->longname),
20062306a36Sopenharmony_ci			 "Diamond Tech. DT-019X, %s at 0x%lx, irq %d, dma %d",
20162306a36Sopenharmony_ci			 chip->name, chip->port, irq[dev], dma8[dev]);
20262306a36Sopenharmony_ci	} else {
20362306a36Sopenharmony_ci		strcpy(card->driver, "ALS100");
20462306a36Sopenharmony_ci		strcpy(card->shortname, "Avance Logic ALS100");
20562306a36Sopenharmony_ci		snprintf(card->longname, sizeof(card->longname),
20662306a36Sopenharmony_ci			 "Avance Logic ALS100, %s at 0x%lx, irq %d, dma %d&%d",
20762306a36Sopenharmony_ci			 chip->name, chip->port, irq[dev], dma8[dev],
20862306a36Sopenharmony_ci			 dma16[dev]);
20962306a36Sopenharmony_ci	}
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	error = snd_sb16dsp_pcm(chip, 0);
21262306a36Sopenharmony_ci	if (error < 0)
21362306a36Sopenharmony_ci		return error;
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	error = snd_sbmixer_new(chip);
21662306a36Sopenharmony_ci	if (error < 0)
21762306a36Sopenharmony_ci		return error;
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci	if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
22062306a36Sopenharmony_ci		int mpu_type = MPU401_HW_ALS100;
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci		if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
22362306a36Sopenharmony_ci			mpu_irq[dev] = -1;
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci		if (pid->driver_data == SB_HW_DT019X)
22662306a36Sopenharmony_ci			mpu_type = MPU401_HW_MPU401;
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci		if (snd_mpu401_uart_new(card, 0,
22962306a36Sopenharmony_ci					mpu_type,
23062306a36Sopenharmony_ci					mpu_port[dev], 0,
23162306a36Sopenharmony_ci					mpu_irq[dev],
23262306a36Sopenharmony_ci					NULL) < 0)
23362306a36Sopenharmony_ci			snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]);
23462306a36Sopenharmony_ci	}
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci	if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
23762306a36Sopenharmony_ci		if (snd_opl3_create(card,
23862306a36Sopenharmony_ci				    fm_port[dev], fm_port[dev] + 2,
23962306a36Sopenharmony_ci				    OPL3_HW_AUTO, 0, &opl3) < 0) {
24062306a36Sopenharmony_ci			snd_printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx\n",
24162306a36Sopenharmony_ci				   fm_port[dev], fm_port[dev] + 2);
24262306a36Sopenharmony_ci		} else {
24362306a36Sopenharmony_ci			error = snd_opl3_timer_new(opl3, 0, 1);
24462306a36Sopenharmony_ci			if (error < 0)
24562306a36Sopenharmony_ci				return error;
24662306a36Sopenharmony_ci			error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
24762306a36Sopenharmony_ci			if (error < 0)
24862306a36Sopenharmony_ci				return error;
24962306a36Sopenharmony_ci		}
25062306a36Sopenharmony_ci	}
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	error = snd_card_register(card);
25362306a36Sopenharmony_ci	if (error < 0)
25462306a36Sopenharmony_ci		return error;
25562306a36Sopenharmony_ci	pnp_set_card_drvdata(pcard, card);
25662306a36Sopenharmony_ci	return 0;
25762306a36Sopenharmony_ci}
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_cistatic unsigned int als100_devices;
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_cistatic int snd_als100_pnp_detect(struct pnp_card_link *card,
26262306a36Sopenharmony_ci				 const struct pnp_card_device_id *id)
26362306a36Sopenharmony_ci{
26462306a36Sopenharmony_ci	static int dev;
26562306a36Sopenharmony_ci	int res;
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	for ( ; dev < SNDRV_CARDS; dev++) {
26862306a36Sopenharmony_ci		if (!enable[dev])
26962306a36Sopenharmony_ci			continue;
27062306a36Sopenharmony_ci		res = snd_card_als100_probe(dev, card, id);
27162306a36Sopenharmony_ci		if (res < 0)
27262306a36Sopenharmony_ci			return res;
27362306a36Sopenharmony_ci		dev++;
27462306a36Sopenharmony_ci		als100_devices++;
27562306a36Sopenharmony_ci		return 0;
27662306a36Sopenharmony_ci	}
27762306a36Sopenharmony_ci	return -ENODEV;
27862306a36Sopenharmony_ci}
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci#ifdef CONFIG_PM
28162306a36Sopenharmony_cistatic int snd_als100_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
28262306a36Sopenharmony_ci{
28362306a36Sopenharmony_ci	struct snd_card *card = pnp_get_card_drvdata(pcard);
28462306a36Sopenharmony_ci	struct snd_card_als100 *acard = card->private_data;
28562306a36Sopenharmony_ci	struct snd_sb *chip = acard->chip;
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
28862306a36Sopenharmony_ci	snd_sbmixer_suspend(chip);
28962306a36Sopenharmony_ci	return 0;
29062306a36Sopenharmony_ci}
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_cistatic int snd_als100_pnp_resume(struct pnp_card_link *pcard)
29362306a36Sopenharmony_ci{
29462306a36Sopenharmony_ci	struct snd_card *card = pnp_get_card_drvdata(pcard);
29562306a36Sopenharmony_ci	struct snd_card_als100 *acard = card->private_data;
29662306a36Sopenharmony_ci	struct snd_sb *chip = acard->chip;
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ci	snd_sbdsp_reset(chip);
29962306a36Sopenharmony_ci	snd_sbmixer_resume(chip);
30062306a36Sopenharmony_ci	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
30162306a36Sopenharmony_ci	return 0;
30262306a36Sopenharmony_ci}
30362306a36Sopenharmony_ci#endif
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_cistatic struct pnp_card_driver als100_pnpc_driver = {
30662306a36Sopenharmony_ci	.flags          = PNP_DRIVER_RES_DISABLE,
30762306a36Sopenharmony_ci	.name		= "als100",
30862306a36Sopenharmony_ci        .id_table       = snd_als100_pnpids,
30962306a36Sopenharmony_ci        .probe          = snd_als100_pnp_detect,
31062306a36Sopenharmony_ci#ifdef CONFIG_PM
31162306a36Sopenharmony_ci	.suspend	= snd_als100_pnp_suspend,
31262306a36Sopenharmony_ci	.resume		= snd_als100_pnp_resume,
31362306a36Sopenharmony_ci#endif
31462306a36Sopenharmony_ci};
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_cistatic int __init alsa_card_als100_init(void)
31762306a36Sopenharmony_ci{
31862306a36Sopenharmony_ci	int err;
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci	err = pnp_register_card_driver(&als100_pnpc_driver);
32162306a36Sopenharmony_ci	if (err)
32262306a36Sopenharmony_ci		return err;
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	if (!als100_devices) {
32562306a36Sopenharmony_ci		pnp_unregister_card_driver(&als100_pnpc_driver);
32662306a36Sopenharmony_ci#ifdef MODULE
32762306a36Sopenharmony_ci		snd_printk(KERN_ERR "no Avance Logic based soundcards found\n");
32862306a36Sopenharmony_ci#endif
32962306a36Sopenharmony_ci		return -ENODEV;
33062306a36Sopenharmony_ci	}
33162306a36Sopenharmony_ci	return 0;
33262306a36Sopenharmony_ci}
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_cistatic void __exit alsa_card_als100_exit(void)
33562306a36Sopenharmony_ci{
33662306a36Sopenharmony_ci	pnp_unregister_card_driver(&als100_pnpc_driver);
33762306a36Sopenharmony_ci}
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_cimodule_init(alsa_card_als100_init)
34062306a36Sopenharmony_cimodule_exit(alsa_card_als100_exit)
341