[RFC][PATCH v6 1/1] alsa: jack: implement software jack injection via debugfs

Hui Wang hui.wang at canonical.com
Sun Jan 24 09:27:55 CET 2021


On 1/22/21 11:13 PM, Takashi Iwai wrote:
> On Fri, 22 Jan 2021 15:14:56 +0100,
> Hui Wang wrote:
>> --- /dev/null
>> +++ b/Documentation/sound/designs/jack-injection.rst
<snip>
>> +   sound/card1/Headphone_Jack# echo 1 > jackin_inject
>> +   to inject plugout:
>> +   sound/card1/Headphone_Jack# echo 0 > jackin_inject
> The lists could be better in a normal format, while only the examples
> with cat and echo should be in verbose format.
Will fix it in v7.
>> diff --git a/sound/core/Kconfig b/sound/core/Kconfig
>> index d4554f376160..a9189f58dc56 100644
>> --- a/sound/core/Kconfig
>> +++ b/sound/core/Kconfig
>> @@ -38,6 +38,15 @@ config SND_JACK_INPUT_DEV
>>   	depends on SND_JACK
>>   	default y if INPUT=y || INPUT=SND
>>   
>> +config SND_JACK_INJECTION_DEBUG
>> +	bool "Sound jack injection interface via debugfs"
>> +	depends on SND_JACK && DEBUG_FS
> Also, could depend on SND_DEBUG for consistency.
OK, will add this dependence.
>
>> diff --git a/sound/core/init.c b/sound/core/init.c
>> index 75aec71c48a8..e7f7cfe1143b 100644
>> --- a/sound/core/init.c
>> +++ b/sound/core/init.c
>> @@ -13,6 +13,7 @@
>>   #include <linux/time.h>
>>   #include <linux/ctype.h>
>>   #include <linux/pm.h>
>> +#include <linux/debugfs.h>
>>   #include <linux/completion.h>
>>   
>>   #include <sound/core.h>
>> @@ -161,6 +162,7 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
>>   {
>>   	struct snd_card *card;
>>   	int err;
>> +	char name[8];
>>   
>>   	if (snd_BUG_ON(!card_ret))
>>   		return -EINVAL;
>> @@ -244,6 +246,10 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
>>   		dev_err(parent, "unable to create card info\n");
>>   		goto __error_ctl;
>>   	}
>> +
>> +	sprintf(name, "card%d", idx);
>> +	card->debugfs_root = debugfs_create_dir(name, sound_debugfs_root);
> It's still an open question whether we want to create the debugfs
> always.  But I guess it's OK, we might want to add more stuff to
> debugfs later.  Or, it makes sense to create only if
> CONFIG_SND_DEBUG=y.
Will add "#ifdef CONFIG_SND_DEBUG" to conditionally create 
debugfs_mount_dir/sound and debugfs_mount_dir/sound/cardN
>
>> +static ssize_t sw_inject_enable_write(struct file *file,
>> +				      const char __user *from, size_t count, loff_t *ppos)
>> +{
>> +	struct snd_jack_kctl *jack_kctl = file->private_data;
>> +	int ret, err;
>> +	unsigned long enable;
>> +	char buf[8] = { 0 };
>> +
>> +	if (count >= 8)
>> +		return -EINVAL;
>> +
>> +	ret = simple_write_to_buffer(buf, count, ppos, from, count);
> The simple_write_to_buffer() doesn't terminate the string by itself,
> hence you need to make sure the string termination before kstrtoul()
> call. e.g.  buf[sizeof(buf)-1] = 0;
>
> And maybe it's easier to make a helper function to that, since it's
> called in multiple places.
>

OK, I will change it as below:

char buf[8] = { 0 };

ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, from, count);

>> +static int parse_mask_bits(unsigned int mask_bits, char *s)
>> +{
>> +	char buf[256];
>> +	int len, i;
>> +
>> +	len = scnprintf(buf, sizeof(buf), "0x%04x", mask_bits);
>> +
>> +	for (i = 0; i < 16; i++)
>> +		if (mask_bits & (1 << i))
>> +			len += scnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
>> +					 " %s", jack_events_name[i]);
>> +
>> +	len += scnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "\n");
>> +
>> +	strcpy(s, buf);
> You need to intermediate buffer if you do a full copy here...
> Just perform the string ops on s with a certain limit.
> Also, you can use strncat() or strlcat() for simplicity.

I will drop intermediate buffer and don't use strcpy() here, and use 
strlcat to replace scnprintf(), the changes like below:

/* the recommended the buffer size is 256 */
static int parse_mask_bits(unsigned int mask_bits, char *buf, size_t 
buf_size)
{
     int i;

     scnprintf(buf, buf_size, "0x%04x", mask_bits);

     for (i = 0; i < 16; i++)
         if (mask_bits & (1 << i)) {
             strlcat(buf, " ", buf_size);
             strlcat(buf, jack_events_name[i], buf_size);
         }
     strlcat(buf, "\n", buf_size);

     return strlen(buf);
}

Thanks,

Hui.

>
> thanks,
>
> Takashi


More information about the Alsa-devel mailing list