brintos

brintos / linux-shallow public Read only

0
0
Text · 17.6 KiB · 4863d6a Raw
709 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * wm8741.c  --  WM8741 ALSA SoC Audio driver4 *5 * Copyright 2010-1 Wolfson Microelectronics plc6 *7 * Author: Ian Lartey <ian@opensource.wolfsonmicro.com>8 */9 10#include <linux/module.h>11#include <linux/moduleparam.h>12#include <linux/init.h>13#include <linux/delay.h>14#include <linux/pm.h>15#include <linux/i2c.h>16#include <linux/spi/spi.h>17#include <linux/of.h>18#include <linux/regmap.h>19#include <linux/regulator/consumer.h>20#include <linux/slab.h>21#include <sound/core.h>22#include <sound/pcm.h>23#include <sound/pcm_params.h>24#include <sound/soc.h>25#include <sound/initval.h>26#include <sound/tlv.h>27 28#include "wm8741.h"29 30#define WM8741_NUM_SUPPLIES 231static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {32	"AVDD",33	"DVDD",34};35 36/* codec private data */37struct wm8741_priv {38	struct wm8741_platform_data pdata;39	struct regmap *regmap;40	struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];41	unsigned int sysclk;42	const struct snd_pcm_hw_constraint_list *sysclk_constraints;43};44 45static const struct reg_default wm8741_reg_defaults[] = {46	{  0, 0x0000 },     /* R0  - DACLLSB Attenuation */47	{  1, 0x0000 },     /* R1  - DACLMSB Attenuation */48	{  2, 0x0000 },     /* R2  - DACRLSB Attenuation */49	{  3, 0x0000 },     /* R3  - DACRMSB Attenuation */50	{  4, 0x0000 },     /* R4  - Volume Control */51	{  5, 0x000A },     /* R5  - Format Control */52	{  6, 0x0000 },     /* R6  - Filter Control */53	{  7, 0x0000 },     /* R7  - Mode Control 1 */54	{  8, 0x0002 },     /* R8  - Mode Control 2 */55	{ 32, 0x0002 },     /* R32 - ADDITONAL_CONTROL_1 */56};57 58static int wm8741_reset(struct snd_soc_component *component)59{60	return snd_soc_component_write(component, WM8741_RESET, 0);61}62 63static const DECLARE_TLV_DB_SCALE(dac_tlv_fine, -12700, 13, 0);64static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 400, 0);65 66static const struct snd_kcontrol_new wm8741_snd_controls_stereo[] = {67SOC_DOUBLE_R_TLV("Fine Playback Volume", WM8741_DACLLSB_ATTENUATION,68		 WM8741_DACRLSB_ATTENUATION, 1, 255, 1, dac_tlv_fine),69SOC_DOUBLE_R_TLV("Playback Volume", WM8741_DACLMSB_ATTENUATION,70		 WM8741_DACRMSB_ATTENUATION, 0, 511, 1, dac_tlv),71};72 73static const struct snd_kcontrol_new wm8741_snd_controls_mono_left[] = {74SOC_SINGLE_TLV("Fine Playback Volume", WM8741_DACLLSB_ATTENUATION,75		 1, 255, 1, dac_tlv_fine),76SOC_SINGLE_TLV("Playback Volume", WM8741_DACLMSB_ATTENUATION,77		 0, 511, 1, dac_tlv),78};79 80static const struct snd_kcontrol_new wm8741_snd_controls_mono_right[] = {81SOC_SINGLE_TLV("Fine Playback Volume", WM8741_DACRLSB_ATTENUATION,82		1, 255, 1, dac_tlv_fine),83SOC_SINGLE_TLV("Playback Volume", WM8741_DACRMSB_ATTENUATION,84		0, 511, 1, dac_tlv),85};86 87static const struct snd_soc_dapm_widget wm8741_dapm_widgets[] = {88SND_SOC_DAPM_DAC("DACL", "Playback", SND_SOC_NOPM, 0, 0),89SND_SOC_DAPM_DAC("DACR", "Playback", SND_SOC_NOPM, 0, 0),90SND_SOC_DAPM_OUTPUT("VOUTLP"),91SND_SOC_DAPM_OUTPUT("VOUTLN"),92SND_SOC_DAPM_OUTPUT("VOUTRP"),93SND_SOC_DAPM_OUTPUT("VOUTRN"),94};95 96static const struct snd_soc_dapm_route wm8741_dapm_routes[] = {97	{ "VOUTLP", NULL, "DACL" },98	{ "VOUTLN", NULL, "DACL" },99	{ "VOUTRP", NULL, "DACR" },100	{ "VOUTRN", NULL, "DACR" },101};102 103static const unsigned int rates_11289[] = {104	44100, 88200,105};106 107static const struct snd_pcm_hw_constraint_list constraints_11289 = {108	.count	= ARRAY_SIZE(rates_11289),109	.list	= rates_11289,110};111 112static const unsigned int rates_12288[] = {113	32000, 48000, 96000,114};115 116static const struct snd_pcm_hw_constraint_list constraints_12288 = {117	.count	= ARRAY_SIZE(rates_12288),118	.list	= rates_12288,119};120 121static const unsigned int rates_16384[] = {122	32000,123};124 125static const struct snd_pcm_hw_constraint_list constraints_16384 = {126	.count	= ARRAY_SIZE(rates_16384),127	.list	= rates_16384,128};129 130static const unsigned int rates_16934[] = {131	44100, 88200,132};133 134static const struct snd_pcm_hw_constraint_list constraints_16934 = {135	.count	= ARRAY_SIZE(rates_16934),136	.list	= rates_16934,137};138 139static const unsigned int rates_18432[] = {140	48000, 96000,141};142 143static const struct snd_pcm_hw_constraint_list constraints_18432 = {144	.count	= ARRAY_SIZE(rates_18432),145	.list	= rates_18432,146};147 148static const unsigned int rates_22579[] = {149	44100, 88200, 176400150};151 152static const struct snd_pcm_hw_constraint_list constraints_22579 = {153	.count	= ARRAY_SIZE(rates_22579),154	.list	= rates_22579,155};156 157static const unsigned int rates_24576[] = {158	32000, 48000, 96000, 192000159};160 161static const struct snd_pcm_hw_constraint_list constraints_24576 = {162	.count	= ARRAY_SIZE(rates_24576),163	.list	= rates_24576,164};165 166static const unsigned int rates_36864[] = {167	48000, 96000, 192000168};169 170static const struct snd_pcm_hw_constraint_list constraints_36864 = {171	.count	= ARRAY_SIZE(rates_36864),172	.list	= rates_36864,173};174 175static int wm8741_startup(struct snd_pcm_substream *substream,176			  struct snd_soc_dai *dai)177{178	struct snd_soc_component *component = dai->component;179	struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);180 181	if (wm8741->sysclk)182		snd_pcm_hw_constraint_list(substream->runtime, 0,183				SNDRV_PCM_HW_PARAM_RATE,184				wm8741->sysclk_constraints);185 186	return 0;187}188 189static int wm8741_hw_params(struct snd_pcm_substream *substream,190			    struct snd_pcm_hw_params *params,191			    struct snd_soc_dai *dai)192{193	struct snd_soc_component *component = dai->component;194	struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);195	unsigned int iface, mode;196	int i;197 198	/* The set of sample rates that can be supported depends on the199	 * MCLK supplied to the CODEC - enforce this.200	 */201	if (!wm8741->sysclk) {202		dev_err(component->dev,203			"No MCLK configured, call set_sysclk() on init or in hw_params\n");204		return -EINVAL;205	}206 207	/* Find a supported LRCLK rate */208	for (i = 0; i < wm8741->sysclk_constraints->count; i++) {209		if (wm8741->sysclk_constraints->list[i] == params_rate(params))210			break;211	}212 213	if (i == wm8741->sysclk_constraints->count) {214		dev_err(component->dev, "LRCLK %d unsupported with MCLK %d\n",215			params_rate(params), wm8741->sysclk);216		return -EINVAL;217	}218 219	/* bit size */220	switch (params_width(params)) {221	case 16:222		iface = 0x0;223		break;224	case 20:225		iface = 0x1;226		break;227	case 24:228		iface = 0x2;229		break;230	case 32:231		iface = 0x3;232		break;233	default:234		dev_dbg(component->dev, "wm8741_hw_params:    Unsupported bit size param = %d",235			params_width(params));236		return -EINVAL;237	}238 239	/* oversampling rate */240	if (params_rate(params) > 96000)241		mode = 0x40;242	else if (params_rate(params) > 48000)243		mode = 0x20;244	else245		mode = 0x00;246 247	dev_dbg(component->dev, "wm8741_hw_params:    bit size param = %d, rate param = %d",248		params_width(params), params_rate(params));249 250	snd_soc_component_update_bits(component, WM8741_FORMAT_CONTROL, WM8741_IWL_MASK,251			    iface);252	snd_soc_component_update_bits(component, WM8741_MODE_CONTROL_1, WM8741_OSR_MASK,253			    mode);254 255	return 0;256}257 258static int wm8741_set_dai_sysclk(struct snd_soc_dai *codec_dai,259		int clk_id, unsigned int freq, int dir)260{261	struct snd_soc_component *component = codec_dai->component;262	struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);263 264	dev_dbg(component->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq);265 266	switch (freq) {267	case 0:268		wm8741->sysclk_constraints = NULL;269		break;270	case 11289600:271		wm8741->sysclk_constraints = &constraints_11289;272		break;273	case 12288000:274		wm8741->sysclk_constraints = &constraints_12288;275		break;276	case 16384000:277		wm8741->sysclk_constraints = &constraints_16384;278		break;279	case 16934400:280		wm8741->sysclk_constraints = &constraints_16934;281		break;282	case 18432000:283		wm8741->sysclk_constraints = &constraints_18432;284		break;285	case 22579200:286	case 33868800:287		wm8741->sysclk_constraints = &constraints_22579;288		break;289	case 24576000:290		wm8741->sysclk_constraints = &constraints_24576;291		break;292	case 36864000:293		wm8741->sysclk_constraints = &constraints_36864;294		break;295	default:296		return -EINVAL;297	}298 299	wm8741->sysclk = freq;300	return 0;301}302 303static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,304		unsigned int fmt)305{306	struct snd_soc_component *component = codec_dai->component;307	unsigned int iface;308 309	/* check master/slave audio interface */310	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {311	case SND_SOC_DAIFMT_CBS_CFS:312		break;313	default:314		return -EINVAL;315	}316 317	/* interface format */318	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {319	case SND_SOC_DAIFMT_I2S:320		iface = 0x08;321		break;322	case SND_SOC_DAIFMT_RIGHT_J:323		iface = 0x00;324		break;325	case SND_SOC_DAIFMT_LEFT_J:326		iface = 0x04;327		break;328	case SND_SOC_DAIFMT_DSP_A:329		iface = 0x0C;330		break;331	case SND_SOC_DAIFMT_DSP_B:332		iface = 0x1C;333		break;334	default:335		return -EINVAL;336	}337 338	/* clock inversion */339	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {340	case SND_SOC_DAIFMT_NB_NF:341		break;342	case SND_SOC_DAIFMT_NB_IF:343		iface |= 0x10;344		break;345	case SND_SOC_DAIFMT_IB_NF:346		iface |= 0x20;347		break;348	case SND_SOC_DAIFMT_IB_IF:349		iface |= 0x30;350		break;351	default:352		return -EINVAL;353	}354 355 356	dev_dbg(component->dev, "wm8741_set_dai_fmt:    Format=%x, Clock Inv=%x\n",357				fmt & SND_SOC_DAIFMT_FORMAT_MASK,358				((fmt & SND_SOC_DAIFMT_INV_MASK)));359 360	snd_soc_component_update_bits(component, WM8741_FORMAT_CONTROL,361			    WM8741_BCP_MASK | WM8741_LRP_MASK | WM8741_FMT_MASK,362			    iface);363 364	return 0;365}366 367static int wm8741_mute(struct snd_soc_dai *codec_dai, int mute, int direction)368{369	struct snd_soc_component *component = codec_dai->component;370 371	snd_soc_component_update_bits(component, WM8741_VOLUME_CONTROL,372			WM8741_SOFT_MASK, !!mute << WM8741_SOFT_SHIFT);373	return 0;374}375 376#define WM8741_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \377			SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \378			SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \379			SNDRV_PCM_RATE_192000)380 381#define WM8741_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\382			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)383 384static const struct snd_soc_dai_ops wm8741_dai_ops = {385	.startup	= wm8741_startup,386	.hw_params	= wm8741_hw_params,387	.set_sysclk	= wm8741_set_dai_sysclk,388	.set_fmt	= wm8741_set_dai_fmt,389	.mute_stream	= wm8741_mute,390	.no_capture_mute = 1,391};392 393static struct snd_soc_dai_driver wm8741_dai = {394	.name = "wm8741",395	.playback = {396		.stream_name = "Playback",397		.channels_min = 2,398		.channels_max = 2,399		.rates = WM8741_RATES,400		.formats = WM8741_FORMATS,401	},402	.ops = &wm8741_dai_ops,403};404 405#ifdef CONFIG_PM406static int wm8741_resume(struct snd_soc_component *component)407{408	snd_soc_component_cache_sync(component);409	return 0;410}411#else412#define wm8741_resume NULL413#endif414 415static int wm8741_configure(struct snd_soc_component *component)416{417	struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);418 419	/* Configure differential mode */420	switch (wm8741->pdata.diff_mode) {421	case WM8741_DIFF_MODE_STEREO:422	case WM8741_DIFF_MODE_STEREO_REVERSED:423	case WM8741_DIFF_MODE_MONO_LEFT:424	case WM8741_DIFF_MODE_MONO_RIGHT:425		snd_soc_component_update_bits(component, WM8741_MODE_CONTROL_2,426				WM8741_DIFF_MASK,427				wm8741->pdata.diff_mode << WM8741_DIFF_SHIFT);428		break;429	default:430		return -EINVAL;431	}432 433	/* Change some default settings - latch VU */434	snd_soc_component_update_bits(component, WM8741_DACLLSB_ATTENUATION,435			WM8741_UPDATELL, WM8741_UPDATELL);436	snd_soc_component_update_bits(component, WM8741_DACLMSB_ATTENUATION,437			WM8741_UPDATELM, WM8741_UPDATELM);438	snd_soc_component_update_bits(component, WM8741_DACRLSB_ATTENUATION,439			WM8741_UPDATERL, WM8741_UPDATERL);440	snd_soc_component_update_bits(component, WM8741_DACRMSB_ATTENUATION,441			WM8741_UPDATERM, WM8741_UPDATERM);442 443	return 0;444}445 446static int wm8741_add_controls(struct snd_soc_component *component)447{448	struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);449 450	switch (wm8741->pdata.diff_mode) {451	case WM8741_DIFF_MODE_STEREO:452	case WM8741_DIFF_MODE_STEREO_REVERSED:453		snd_soc_add_component_controls(component,454				wm8741_snd_controls_stereo,455				ARRAY_SIZE(wm8741_snd_controls_stereo));456		break;457	case WM8741_DIFF_MODE_MONO_LEFT:458		snd_soc_add_component_controls(component,459				wm8741_snd_controls_mono_left,460				ARRAY_SIZE(wm8741_snd_controls_mono_left));461		break;462	case WM8741_DIFF_MODE_MONO_RIGHT:463		snd_soc_add_component_controls(component,464				wm8741_snd_controls_mono_right,465				ARRAY_SIZE(wm8741_snd_controls_mono_right));466		break;467	default:468		return -EINVAL;469	}470 471	return 0;472}473 474static int wm8741_probe(struct snd_soc_component *component)475{476	struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);477	int ret = 0;478 479	ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),480				    wm8741->supplies);481	if (ret != 0) {482		dev_err(component->dev, "Failed to enable supplies: %d\n", ret);483		goto err_get;484	}485 486	ret = wm8741_reset(component);487	if (ret < 0) {488		dev_err(component->dev, "Failed to issue reset\n");489		goto err_enable;490	}491 492	ret = wm8741_configure(component);493	if (ret < 0) {494		dev_err(component->dev, "Failed to change default settings\n");495		goto err_enable;496	}497 498	ret = wm8741_add_controls(component);499	if (ret < 0) {500		dev_err(component->dev, "Failed to add controls\n");501		goto err_enable;502	}503 504	dev_dbg(component->dev, "Successful registration\n");505	return ret;506 507err_enable:508	regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);509err_get:510	return ret;511}512 513static void wm8741_remove(struct snd_soc_component *component)514{515	struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);516 517	regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);518}519 520static const struct snd_soc_component_driver soc_component_dev_wm8741 = {521	.probe			= wm8741_probe,522	.remove			= wm8741_remove,523	.resume			= wm8741_resume,524	.dapm_widgets		= wm8741_dapm_widgets,525	.num_dapm_widgets	= ARRAY_SIZE(wm8741_dapm_widgets),526	.dapm_routes		= wm8741_dapm_routes,527	.num_dapm_routes	= ARRAY_SIZE(wm8741_dapm_routes),528	.idle_bias_on		= 1,529	.use_pmdown_time	= 1,530	.endianness		= 1,531};532 533static const struct of_device_id wm8741_of_match[] = {534	{ .compatible = "wlf,wm8741", },535	{ }536};537MODULE_DEVICE_TABLE(of, wm8741_of_match);538 539static const struct regmap_config wm8741_regmap = {540	.reg_bits = 7,541	.val_bits = 9,542	.max_register = WM8741_MAX_REGISTER,543 544	.reg_defaults = wm8741_reg_defaults,545	.num_reg_defaults = ARRAY_SIZE(wm8741_reg_defaults),546	.cache_type = REGCACHE_MAPLE,547};548 549static int wm8741_set_pdata(struct device *dev, struct wm8741_priv *wm8741)550{551	const struct wm8741_platform_data *pdata = dev_get_platdata(dev);552	u32 diff_mode;553 554	if (dev->of_node) {555		if (of_property_read_u32(dev->of_node, "diff-mode", &diff_mode)556				>= 0)557			wm8741->pdata.diff_mode = diff_mode;558	} else {559		if (pdata != NULL)560			memcpy(&wm8741->pdata, pdata, sizeof(wm8741->pdata));561	}562 563	return 0;564}565 566#if IS_ENABLED(CONFIG_I2C)567static int wm8741_i2c_probe(struct i2c_client *i2c)568{569	struct wm8741_priv *wm8741;570	int ret, i;571 572	wm8741 = devm_kzalloc(&i2c->dev, sizeof(struct wm8741_priv),573			      GFP_KERNEL);574	if (wm8741 == NULL)575		return -ENOMEM;576 577	for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)578		wm8741->supplies[i].supply = wm8741_supply_names[i];579 580	ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8741->supplies),581				      wm8741->supplies);582	if (ret != 0) {583		dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);584		return ret;585	}586 587	wm8741->regmap = devm_regmap_init_i2c(i2c, &wm8741_regmap);588	if (IS_ERR(wm8741->regmap)) {589		ret = PTR_ERR(wm8741->regmap);590		dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);591		return ret;592	}593 594	ret = wm8741_set_pdata(&i2c->dev, wm8741);595	if (ret != 0) {596		dev_err(&i2c->dev, "Failed to set pdata: %d\n", ret);597		return ret;598	}599 600	i2c_set_clientdata(i2c, wm8741);601 602	ret = devm_snd_soc_register_component(&i2c->dev,603				     &soc_component_dev_wm8741, &wm8741_dai, 1);604 605	return ret;606}607 608static const struct i2c_device_id wm8741_i2c_id[] = {609	{ "wm8741" },610	{ }611};612MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id);613 614static struct i2c_driver wm8741_i2c_driver = {615	.driver = {616		.name = "wm8741",617		.of_match_table = wm8741_of_match,618	},619	.probe = wm8741_i2c_probe,620	.id_table = wm8741_i2c_id,621};622#endif623 624#if defined(CONFIG_SPI_MASTER)625static int wm8741_spi_probe(struct spi_device *spi)626{627	struct wm8741_priv *wm8741;628	int ret, i;629 630	wm8741 = devm_kzalloc(&spi->dev, sizeof(struct wm8741_priv),631			     GFP_KERNEL);632	if (wm8741 == NULL)633		return -ENOMEM;634 635	for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)636		wm8741->supplies[i].supply = wm8741_supply_names[i];637 638	ret = devm_regulator_bulk_get(&spi->dev, ARRAY_SIZE(wm8741->supplies),639				      wm8741->supplies);640	if (ret != 0) {641		dev_err(&spi->dev, "Failed to request supplies: %d\n", ret);642		return ret;643	}644 645	wm8741->regmap = devm_regmap_init_spi(spi, &wm8741_regmap);646	if (IS_ERR(wm8741->regmap)) {647		ret = PTR_ERR(wm8741->regmap);648		dev_err(&spi->dev, "Failed to init regmap: %d\n", ret);649		return ret;650	}651 652	ret = wm8741_set_pdata(&spi->dev, wm8741);653	if (ret != 0) {654		dev_err(&spi->dev, "Failed to set pdata: %d\n", ret);655		return ret;656	}657 658	spi_set_drvdata(spi, wm8741);659 660	ret = devm_snd_soc_register_component(&spi->dev,661			&soc_component_dev_wm8741, &wm8741_dai, 1);662	return ret;663}664 665static struct spi_driver wm8741_spi_driver = {666	.driver = {667		.name	= "wm8741",668		.of_match_table = wm8741_of_match,669	},670	.probe		= wm8741_spi_probe,671};672#endif /* CONFIG_SPI_MASTER */673 674static int __init wm8741_modinit(void)675{676	int ret = 0;677 678#if IS_ENABLED(CONFIG_I2C)679	ret = i2c_add_driver(&wm8741_i2c_driver);680	if (ret != 0)681		pr_err("Failed to register WM8741 I2C driver: %d\n", ret);682#endif683#if defined(CONFIG_SPI_MASTER)684	ret = spi_register_driver(&wm8741_spi_driver);685	if (ret != 0) {686		printk(KERN_ERR "Failed to register wm8741 SPI driver: %d\n",687		       ret);688	}689#endif690 691	return ret;692}693module_init(wm8741_modinit);694 695static void __exit wm8741_exit(void)696{697#if defined(CONFIG_SPI_MASTER)698	spi_unregister_driver(&wm8741_spi_driver);699#endif700#if IS_ENABLED(CONFIG_I2C)701	i2c_del_driver(&wm8741_i2c_driver);702#endif703}704module_exit(wm8741_exit);705 706MODULE_DESCRIPTION("ASoC WM8741 driver");707MODULE_AUTHOR("Ian Lartey <ian@opensource.wolfsonmicro.com>");708MODULE_LICENSE("GPL");709