@@ -1477,18 +1477,8 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
1477
1477
}
1478
1478
EXPORT_SYMBOL_GPL (snd_hda_mixer_amp_volume_put );
1479
1479
1480
- /**
1481
- * snd_hda_mixer_amp_volume_put - TLV callback for a standard AMP mixer volume
1482
- * @kcontrol: ctl element
1483
- * @op_flag: operation flag
1484
- * @size: byte size of input TLV
1485
- * @_tlv: TLV data
1486
- *
1487
- * The control element is supposed to have the private_value field
1488
- * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1489
- */
1490
- int snd_hda_mixer_amp_tlv (struct snd_kcontrol * kcontrol , int op_flag ,
1491
- unsigned int size , unsigned int __user * _tlv )
1480
+ /* inquiry the amp caps and convert to TLV */
1481
+ static void get_ctl_amp_tlv (struct snd_kcontrol * kcontrol , unsigned int * tlv )
1492
1482
{
1493
1483
struct hda_codec * codec = snd_kcontrol_chip (kcontrol );
1494
1484
hda_nid_t nid = get_amp_nid (kcontrol );
@@ -1497,8 +1487,6 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1497
1487
bool min_mute = get_amp_min_mute (kcontrol );
1498
1488
u32 caps , val1 , val2 ;
1499
1489
1500
- if (size < 4 * sizeof (unsigned int ))
1501
- return - ENOMEM ;
1502
1490
caps = query_amp_caps (codec , nid , dir );
1503
1491
val2 = (caps & AC_AMPCAP_STEP_SIZE ) >> AC_AMPCAP_STEP_SIZE_SHIFT ;
1504
1492
val2 = (val2 + 1 ) * 25 ;
@@ -1507,13 +1495,31 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1507
1495
val1 = ((int )val1 ) * ((int )val2 );
1508
1496
if (min_mute || (caps & AC_AMPCAP_MIN_MUTE ))
1509
1497
val2 |= TLV_DB_SCALE_MUTE ;
1510
- if (put_user (SNDRV_CTL_TLVT_DB_SCALE , _tlv ))
1511
- return - EFAULT ;
1512
- if (put_user (2 * sizeof (unsigned int ), _tlv + 1 ))
1513
- return - EFAULT ;
1514
- if (put_user (val1 , _tlv + 2 ))
1515
- return - EFAULT ;
1516
- if (put_user (val2 , _tlv + 3 ))
1498
+ tlv [0 ] = SNDRV_CTL_TLVT_DB_SCALE ;
1499
+ tlv [1 ] = 2 * sizeof (unsigned int );
1500
+ tlv [2 ] = val1 ;
1501
+ tlv [3 ] = val2 ;
1502
+ }
1503
+
1504
+ /**
1505
+ * snd_hda_mixer_amp_volume_put - TLV callback for a standard AMP mixer volume
1506
+ * @kcontrol: ctl element
1507
+ * @op_flag: operation flag
1508
+ * @size: byte size of input TLV
1509
+ * @_tlv: TLV data
1510
+ *
1511
+ * The control element is supposed to have the private_value field
1512
+ * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1513
+ */
1514
+ int snd_hda_mixer_amp_tlv (struct snd_kcontrol * kcontrol , int op_flag ,
1515
+ unsigned int size , unsigned int __user * _tlv )
1516
+ {
1517
+ unsigned int tlv [4 ];
1518
+
1519
+ if (size < 4 * sizeof (unsigned int ))
1520
+ return - ENOMEM ;
1521
+ get_ctl_amp_tlv (kcontrol , tlv );
1522
+ if (copy_to_user (_tlv , tlv , sizeof (tlv )))
1517
1523
return - EFAULT ;
1518
1524
return 0 ;
1519
1525
}
@@ -1807,13 +1813,10 @@ static int get_kctl_0dB_offset(struct hda_codec *codec,
1807
1813
const int * tlv = NULL ;
1808
1814
int val = -1 ;
1809
1815
1810
- if (kctl -> vd [0 ].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK ) {
1811
- /* FIXME: set_fs() hack for obtaining user-space TLV data */
1812
- mm_segment_t fs = get_fs ();
1813
- set_fs (get_ds ());
1814
- if (!kctl -> tlv .c (kctl , 0 , sizeof (_tlv ), _tlv ))
1815
- tlv = _tlv ;
1816
- set_fs (fs );
1816
+ if ((kctl -> vd [0 ].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK ) &&
1817
+ kctl -> tlv .c == snd_hda_mixer_amp_tlv ) {
1818
+ get_ctl_amp_tlv (kctl , _tlv );
1819
+ tlv = _tlv ;
1817
1820
} else if (kctl -> vd [0 ].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ )
1818
1821
tlv = kctl -> tlv .p ;
1819
1822
if (tlv && tlv [0 ] == SNDRV_CTL_TLVT_DB_SCALE ) {
0 commit comments